Don't rewrite package_config and package_graph if unchanged (#4549)
diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart index 36719a1..0f9779b 100644 --- a/lib/src/entrypoint.dart +++ b/lib/src/entrypoint.dart
@@ -392,6 +392,9 @@ /// Writes the .dart_tool/package_config.json file and workspace references to /// it. /// + /// Compares it to the existing .dart_tool/package_config.json and does not + /// rewrite it unless it is + /// /// Also writes the .dart_tool.package_graph.json file. /// /// If the workspace is non-trivial: For each package in the workspace write: @@ -399,7 +402,8 @@ /// package dir. Future<void> writePackageConfigFiles() async { ensureDir(p.dirname(packageConfigPath)); - writeTextFile( + + _writeIfDifferent( packageConfigPath, await _packageConfigFile( cache, @@ -410,7 +414,8 @@ ?.effectiveConstraint, ), ); - writeTextFile(packageGraphPath, await _packageGraphFile(cache)); + _writeIfDifferent(packageGraphPath, await _packageGraphFile(cache)); + if (workspaceRoot.workspaceChildren.isNotEmpty) { for (final package in workspaceRoot.transitiveWorkspace) { final workspaceRefDir = p.join(package.dir, '.dart_tool', 'pub'); @@ -501,7 +506,6 @@ final packageConfig = PackageConfig( configVersion: 2, packages: entries, - generated: DateTime.now(), generator: 'pub', generatorVersion: sdk.version, additionalProperties: { @@ -520,6 +524,17 @@ return '$jsonText\n'; } + void _writeIfDifferent(String path, String newContent) { + // Compare to the present package_config.json + // For purposes of equality we don't care about the `generated` timestamp. + final originalText = tryReadTextFile(path); + if (originalText != newContent) { + writeTextFile(path, newContent); + } else { + log.fine('`$path` is unchanged. Not rewriting.'); + } + } + /// Gets all dependencies of the [workspaceRoot] package. /// /// Performs version resolution according to [SolveType].
diff --git a/lib/src/package_config.dart b/lib/src/package_config.dart index 408d876..c5d330b 100644 --- a/lib/src/package_config.dart +++ b/lib/src/package_config.dart
@@ -19,11 +19,6 @@ /// Packages configured. List<PackageConfigEntry> packages; - /// Date-time the `.dart_tool/package_config.json` file was generated. - /// - /// `null` if not given. - DateTime? generated; - /// Tool that generated the `.dart_tool/package_config.json` file. /// /// For `pub` this is always `'pub'`. @@ -46,7 +41,6 @@ PackageConfig({ required this.configVersion, required this.packages, - this.generated, this.generator, this.generatorVersion, Map<String, dynamic>? additionalProperties, @@ -98,16 +92,6 @@ packages.add(PackageConfigEntry.fromJson(entry as Object)); } - // Read the 'generated' property - DateTime? generated; - final generatedRaw = root['generated']; - if (generatedRaw != null) { - if (generatedRaw is! String) { - throwFormatException('generated', 'must be a string, if given'); - } - generated = DateTime.parse(generatedRaw); - } - // Read the 'generator' property final generator = root['generator']; if (generator is! String?) { @@ -136,7 +120,6 @@ return PackageConfig( configVersion: configVersion, packages: packages, - generated: generated, generator: generator, generatorVersion: generatorVersion, additionalProperties: Map.fromEntries( @@ -158,7 +141,6 @@ Map<String, Object?> toJson() => { 'configVersion': configVersion, 'packages': packages.map((p) => p.toJson()).toList(), - 'generated': generated?.toUtc().toIso8601String(), 'generator': generator, 'generatorVersion': generatorVersion?.toString(), }..addAll(additionalProperties);
diff --git a/test/descriptor/package_config.dart b/test/descriptor/package_config.dart index fb7996d..8aad157 100644 --- a/test/descriptor/package_config.dart +++ b/test/descriptor/package_config.dart
@@ -28,7 +28,6 @@ packages: _packages, generatorVersion: Version.parse(_generatorVersion), generator: 'pub', - generated: DateTime.now().toUtc(), additionalProperties: { 'pubCache': p.toUri(_pubCache).toString(), if (_flutterRoot != null) @@ -94,9 +93,6 @@ ); final expected = PackageConfig.fromJson(_config.toJson()); - // omit generated date-time and packages - expected.generated = null; // comparing timestamps is unnecessary. - config.generated = null; expected.packages = []; // Already compared packages (ignoring ordering) config.packages = []; expect(
diff --git a/test/package_config_file_test.dart b/test/package_config_file_test.dart index c4c59c0..b924c22 100644 --- a/test/package_config_file_test.dart +++ b/test/package_config_file_test.dart
@@ -2,10 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:convert'; +import 'dart:io'; + import 'package:path/path.dart' as p; import 'package:pub/src/exit_codes.dart' as exit_codes; import 'package:pub/src/package_config.dart'; import 'package:test/test.dart'; +import 'package:test_descriptor/test_descriptor.dart'; import 'descriptor.dart' as d; import 'test_pub.dart'; @@ -308,4 +312,43 @@ ]).validate(); }); }); + + test( + 'package_config and package_graph are not rewritten if unchanged', + () async { + final server = await servePackages(); + server.serve('foo', '1.0.0'); + + await d.appDir(dependencies: {'foo': 'any'}).create(); + + await pubGet(); + final packageConfigFile = File( + p.join(sandbox, appPath, '.dart_tool', 'package_config.json'), + ); + final packageConfig = jsonDecode(packageConfigFile.readAsStringSync()); + final packageConfigTimestamp = packageConfigFile.lastModifiedSync(); + final packageGraphFile = File( + p.join(sandbox, appPath, '.dart_tool', 'package_graph.json'), + ); + final packageGraph = jsonDecode(packageGraphFile.readAsStringSync()); + final packageGraphTimestamp = packageGraphFile.lastModifiedSync(); + final s = p.separator; + await pubGet( + silent: allOf( + contains( + '`.dart_tool${s}package_config.json` is unchanged. Not rewriting.', + ), + contains( + '`.dart_tool${s}package_graph.json` is unchanged. Not rewriting.', + ), + ), + ); + + expect(packageConfig, jsonDecode(packageConfigFile.readAsStringSync())); + expect(packageConfigFile.lastModifiedSync(), packageConfigTimestamp); + + expect(packageGraph, jsonDecode(packageGraphFile.readAsStringSync())); + expect(packageGraphFile.lastModifiedSync(), packageGraphTimestamp); + }, + ); }
diff --git a/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt b/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt index 58cf843..41f85c0 100644 --- a/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt +++ b/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt
@@ -122,7 +122,6 @@ [E] | "languageVersion": "3.0" [E] | } [E] | ], -[E] | "generated": "$TIME", [E] | "generator": "pub", [E] | "generatorVersion": "3.1.2+3", [E] | "pubCache": "file://$SANDBOX/cache" @@ -309,7 +308,6 @@ | "languageVersion": "3.0" | } | ], - | "generated": "$TIME", | "generator": "pub", | "generatorVersion": "3.1.2+3", | "pubCache": "file://$SANDBOX/cache"