From feb3cb565464addc5b3283b9d73a3e5024ab40e8 Mon Sep 17 00:00:00 2001 From: Sigurd Meldgaard Date: Tue, 27 May 2025 13:17:08 +0000 Subject: [PATCH 1/2] Don't rewrite pubspec.lock if not modified --- lib/src/entrypoint.dart | 15 +------ lib/src/io.dart | 11 +++++ lib/src/lock_file.dart | 2 +- test/package_config_file_test.dart | 69 ++++++++++++++++-------------- 4 files changed, 50 insertions(+), 47 deletions(-) diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart index f508969b89..759f460af7 100644 --- a/lib/src/entrypoint.dart +++ b/lib/src/entrypoint.dart @@ -405,7 +405,7 @@ See $workspacesDocUrl for more information.''', Future writePackageConfigFiles() async { ensureDir(p.dirname(packageConfigPath)); - _writeIfDifferent( + writeTextFilesIfDifferent( packageConfigPath, await _packageConfigFile( cache, @@ -416,7 +416,7 @@ See $workspacesDocUrl for more information.''', ?.effectiveConstraint, ), ); - _writeIfDifferent(packageGraphPath, await _packageGraphFile(cache)); + writeTextFilesIfDifferent(packageGraphPath, await _packageGraphFile(cache)); if (workspaceRoot.workspaceChildren.isNotEmpty) { for (final package in workspaceRoot.transitiveWorkspace) { @@ -526,17 +526,6 @@ See $workspacesDocUrl for more information.''', 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/io.dart b/lib/src/io.dart index 608bf873a8..070d2c96b5 100644 --- a/lib/src/io.dart +++ b/lib/src/io.dart @@ -257,6 +257,17 @@ void writeTextFile( File(file).writeAsStringSync(contents, encoding: encoding); } +void writeTextFilesIfDifferent(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.'); + } +} + /// Reads the contents of the binary file [file]. void writeBinaryFile(String file, Uint8List data) { log.io('Writing ${data.length} bytes to file $file.'); diff --git a/lib/src/lock_file.dart b/lib/src/lock_file.dart index 4d5f14bb2f..f83ac41243 100644 --- a/lib/src/lock_file.dart +++ b/lib/src/lock_file.dart @@ -406,7 +406,7 @@ ${yamlToString(data)} detectWindowsLineEndings(readTextFile(lockFilePath)); final serialized = serialize(p.dirname(lockFilePath), cache); - writeTextFile( + writeTextFilesIfDifferent( lockFilePath, windowsLineEndings ? serialized.replaceAll('\n', '\r\n') : serialized, ); diff --git a/test/package_config_file_test.dart b/test/package_config_file_test.dart index b924c222c2..150a8f9c54 100644 --- a/test/package_config_file_test.dart +++ b/test/package_config_file_test.dart @@ -313,42 +313,45 @@ void main() { }); }); - test( - 'package_config and package_graph are not rewritten if unchanged', - () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + test('pubspec.lock 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 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.', - ), + await pubGet(); + final packageConfigFile = File( + p.join(sandbox, appPath, '.dart_tool', 'package_config.json'), + ); + final lockFile = File(p.join(sandbox, appPath, 'pubspec.lock')); + final packageConfig = jsonDecode(packageConfigFile.readAsStringSync()); + final packageConfigTimestamp = packageConfigFile.lastModifiedSync(); + final lockfileTimestamp = lockFile.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.', + ), + ), + ); + // The resolution of timestamps is not that good. + await Future.delayed(const Duration(seconds: 1)); + expect(packageConfig, jsonDecode(packageConfigFile.readAsStringSync())); + expect(packageConfigFile.lastModifiedSync(), packageConfigTimestamp); - expect(packageConfig, jsonDecode(packageConfigFile.readAsStringSync())); - expect(packageConfigFile.lastModifiedSync(), packageConfigTimestamp); + expect(packageGraph, jsonDecode(packageGraphFile.readAsStringSync())); + expect(packageGraphFile.lastModifiedSync(), packageGraphTimestamp); - expect(packageGraph, jsonDecode(packageGraphFile.readAsStringSync())); - expect(packageGraphFile.lastModifiedSync(), packageGraphTimestamp); - }, - ); + expect(lockFile.lastModifiedSync(), lockfileTimestamp); + }); } From 7179a687f3e1db12807420394b138a3f87ef52af Mon Sep 17 00:00:00 2001 From: Sigurd Meldgaard Date: Wed, 28 May 2025 08:03:00 +0000 Subject: [PATCH 2/2] Same for workspace_ref --- lib/src/entrypoint.dart | 6 +++--- lib/src/io.dart | 2 +- lib/src/lock_file.dart | 2 +- test/package_config_file_test.dart | 32 +++++++++++++++++++++++++----- 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart index 759f460af7..43e371349a 100644 --- a/lib/src/entrypoint.dart +++ b/lib/src/entrypoint.dart @@ -405,7 +405,7 @@ See $workspacesDocUrl for more information.''', Future writePackageConfigFiles() async { ensureDir(p.dirname(packageConfigPath)); - writeTextFilesIfDifferent( + writeTextFileIfDifferent( packageConfigPath, await _packageConfigFile( cache, @@ -416,7 +416,7 @@ See $workspacesDocUrl for more information.''', ?.effectiveConstraint, ), ); - writeTextFilesIfDifferent(packageGraphPath, await _packageGraphFile(cache)); + writeTextFileIfDifferent(packageGraphPath, await _packageGraphFile(cache)); if (workspaceRoot.workspaceChildren.isNotEmpty) { for (final package in workspaceRoot.transitiveWorkspace) { @@ -430,7 +430,7 @@ See $workspacesDocUrl for more information.''', final workspaceRef = const JsonEncoder.withIndent( ' ', ).convert({'workspaceRoot': relativeRootPath}); - writeTextFile(workspaceRefPath, '$workspaceRef\n'); + writeTextFileIfDifferent(workspaceRefPath, '$workspaceRef\n'); } } } diff --git a/lib/src/io.dart b/lib/src/io.dart index 070d2c96b5..b7d02ae13b 100644 --- a/lib/src/io.dart +++ b/lib/src/io.dart @@ -257,7 +257,7 @@ void writeTextFile( File(file).writeAsStringSync(contents, encoding: encoding); } -void writeTextFilesIfDifferent(String path, String newContent) { +void writeTextFileIfDifferent(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); diff --git a/lib/src/lock_file.dart b/lib/src/lock_file.dart index f83ac41243..dc688e91f8 100644 --- a/lib/src/lock_file.dart +++ b/lib/src/lock_file.dart @@ -406,7 +406,7 @@ ${yamlToString(data)} detectWindowsLineEndings(readTextFile(lockFilePath)); final serialized = serialize(p.dirname(lockFilePath), cache); - writeTextFilesIfDifferent( + writeTextFileIfDifferent( lockFilePath, windowsLineEndings ? serialized.replaceAll('\n', '\r\n') : serialized, ); diff --git a/test/package_config_file_test.dart b/test/package_config_file_test.dart index 150a8f9c54..f7a58c290b 100644 --- a/test/package_config_file_test.dart +++ b/test/package_config_file_test.dart @@ -313,26 +313,46 @@ void main() { }); }); - test('pubspec.lock package_config and package_graph are not rewritten if' - ' unchanged', () async { + test('pubspec.lock, package_config, package_graph and workspace_ref ' + 'are not rewritten if unchanged', () async { final server = await servePackages(); server.serve('foo', '1.0.0'); - await d.appDir(dependencies: {'foo': 'any'}).create(); + await d.dir(appPath, [ + d.appPubspec( + dependencies: {'foo': 'any'}, + extras: { + 'workspace': ['foo'], + 'environment': {'sdk': '^3.5.0'}, + }, + ), + d.dir('foo', [d.libPubspec('foo', '1.0.0', resolutionWorkspace: true)]), + ]).create(); - await pubGet(); + await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'}); final packageConfigFile = File( p.join(sandbox, appPath, '.dart_tool', 'package_config.json'), ); - final lockFile = File(p.join(sandbox, appPath, 'pubspec.lock')); final packageConfig = jsonDecode(packageConfigFile.readAsStringSync()); final packageConfigTimestamp = packageConfigFile.lastModifiedSync(); + final lockFile = File(p.join(sandbox, appPath, 'pubspec.lock')); final lockfileTimestamp = lockFile.lastModifiedSync(); final packageGraphFile = File( p.join(sandbox, appPath, '.dart_tool', 'package_graph.json'), ); final packageGraph = jsonDecode(packageGraphFile.readAsStringSync()); final packageGraphTimestamp = packageGraphFile.lastModifiedSync(); + final workspaceRefFile = File( + p.join( + sandbox, + appPath, + 'foo', + '.dart_tool', + 'pub', + 'workspace_ref.json', + ), + ); + final workspaceRefTimestamp = workspaceRefFile.lastModifiedSync(); final s = p.separator; await pubGet( silent: allOf( @@ -343,6 +363,7 @@ void main() { '`.dart_tool${s}package_graph.json` is unchanged. Not rewriting.', ), ), + environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'}, ); // The resolution of timestamps is not that good. await Future.delayed(const Duration(seconds: 1)); @@ -353,5 +374,6 @@ void main() { expect(packageGraphFile.lastModifiedSync(), packageGraphTimestamp); expect(lockFile.lastModifiedSync(), lockfileTimestamp); + expect(workspaceRefFile.lastModifiedSync(), workspaceRefTimestamp); }); }