Issue 44131. Handle .dart_tool/package_config.json file change, re-configure with new Packages.
Bug: https://github.com/dart-lang/sdk/issues/44131
Change-Id: I4c843da4c6cecea5e334ba6b73cffa42be6d80ea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171360
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 5c09be3..c37c64c 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -887,9 +887,9 @@
}
void _checkForPackagespecUpdate(String path, ContextInfo info) {
- // Check to see if this is the .packages file for this context and if so,
- // update the context's source factory.
- if (pathContext.basename(path) == PACKAGE_SPEC_NAME) {
+ // Check to see if this is `.dart_tool/package_config.json` or `.packages`
+ // file for this context and if so, update the context's source factory.
+ if (_isPackageConfigJsonFilePath(path) || _isDotPackagesFilePath(path)) {
var driver = info.analysisDriver;
if (driver == null) {
// I suspect that this happens as a result of a race condition: server
@@ -1249,6 +1249,9 @@
if (info.hasDependency(path)) {
_recomputeFolderDisposition(info);
}
+
+ _checkForPackagespecUpdate(path, info);
+
// maybe excluded globally
if (_isExcluded(path) ||
_isContainedInDotFolder(info.folder.path, path) ||
@@ -1283,7 +1286,7 @@
return;
}
}
- if (_isPackagespec(path)) {
+ if (_isDotPackagesFilePath(path)) {
// Check for a sibling pubspec.yaml file.
if (!resourceProvider
.getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
@@ -1323,7 +1326,7 @@
return;
}
}
- if (_isPackagespec(path)) {
+ if (_isDotPackagesFilePath(path)) {
// Check for a sibling pubspec.yaml file.
if (!resourceProvider
.getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
@@ -1352,7 +1355,6 @@
}
}
}
- _checkForPackagespecUpdate(path, info);
_checkForAnalysisOptionsUpdate(path, info);
_checkForDataFileUpdate(path, info);
_checkForPubspecUpdate(path, info);
@@ -1388,6 +1390,10 @@
/// to specify data-driven fixes.
bool _isDataFile(String path) => pathContext.basename(path) == dataFileName;
+ bool _isDotPackagesFilePath(String path) {
+ return pathContext.basename(path) == PACKAGE_SPEC_NAME;
+ }
+
/// Returns `true` if the given [path] is excluded by [excludedPaths].
bool _isExcluded(String path) => _isExcludedBy(excludedPaths, path);
@@ -1415,8 +1421,12 @@
bool _isManifest(String path) => pathContext.basename(path) == MANIFEST_NAME;
- bool _isPackagespec(String path) =>
- pathContext.basename(path) == PACKAGE_SPEC_NAME;
+ bool _isPackageConfigJsonFilePath(String path) {
+ var components = pathContext.split(path);
+ return components.length > 2 &&
+ components[components.length - 1] == 'package_config.json' &&
+ components[components.length - 2] == '.dart_tool';
+ }
bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME;
@@ -1477,8 +1487,13 @@
var builder = callbacks.createContextBuilder(info.folder);
var options = builder.getAnalysisOptions(contextRoot,
contextRoot: driver.contextRoot);
+ var packages = builder.createPackageMap(contextRoot);
var factory = builder.createSourceFactory(contextRoot);
- driver.configure(analysisOptions: options, sourceFactory: factory);
+ driver.configure(
+ analysisOptions: options,
+ packages: packages,
+ sourceFactory: factory,
+ );
callbacks.analysisOptionsUpdated(driver);
}
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 28ba464..a6b4251 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -23,6 +23,7 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/util/glob.dart';
import 'package:linter/src/rules.dart';
@@ -1490,6 +1491,34 @@
});
}
+ Future<void> test_watch_modifyPackageConfigJson() {
+ var packageConfigPath = '$projPath/.dart_tool/package_config.json';
+ var filePath = convertPath('$projPath/bin/main.dart');
+
+ resourceProvider.newFile(packageConfigPath, '');
+ resourceProvider.newFile(filePath, 'library main;');
+
+ manager.setRoots(<String>[projPath], <String>[]);
+
+ var filePaths = callbacks.currentFilePaths;
+ expect(filePaths, hasLength(1));
+ expect(filePaths, contains(filePath));
+ expect(_currentPackageMap, isEmpty);
+
+ // update .dart_tool/package_config.json
+ callbacks.now++;
+ resourceProvider.modifyFile(
+ packageConfigPath,
+ (PackageConfigFileBuilder()..add(name: 'my', rootPath: '../'))
+ .toContent(toUriStr: toUriStr),
+ );
+
+ return pumpEventQueue().then((_) {
+ // verify new package info
+ expect(_currentPackageMap.keys, unorderedEquals(['my']));
+ });
+ }
+
Future<void> test_watch_modifyPackagespec() {
var packagesPath = convertPath('$projPath/.packages');
var filePath = convertPath('$projPath/bin/main.dart');