Change to only look for package_config.json if asked for .packages by name. (#78)
Some clean-up.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1cd45d0..0b5e156 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.9.2
+
+- Updated to support new rules for picking `package_config.json` over
+ a specified `.packages`.
+
## 1.9.1
- Remove accidental transitive import of `dart:io` from entrypoints that are
diff --git a/lib/package_config.dart b/lib/package_config.dart
index bca865d..1113ac8 100644
--- a/lib/package_config.dart
+++ b/lib/package_config.dart
@@ -24,9 +24,10 @@
/// It is considered a `package_config.json` file if its first character
/// is a `{`.
///
-/// If the file is a `.packages` file and [preferNewest] is true, the default,
-/// also checks if there is a `.dart_tool/package_config.json` file next to the original file,
-/// and if so, loads that instead.
+/// If the file is a `.packages` file (the file name is `.packages`)
+/// and [preferNewest] is true, the default, also checks if there is
+/// a `.dart_tool/package_config.json` file next
+/// to the original file, and if so, loads that instead.
/// If [preferNewest] is set to false, a directly specified `.packages` file
/// is loaded even if there is an available `package_config.json` file.
/// The caller can determine this from the [PackageConfig.version]
@@ -50,6 +51,7 @@
/// non-whitespace character is a `{`.
///
/// If [preferNewest] is true, the default, and the file is a `.packages` file,
+/// as determined by its file name being `.packages`,
/// first checks if there is a `.dart_tool/package_config.json` file
/// next to the original file, and if so, loads that instead.
/// The [file] *must not* be a `package:` URI.
diff --git a/lib/src/package_config_io.dart b/lib/src/package_config_io.dart
index 954be6b..31bc1cc 100644
--- a/lib/src/package_config_io.dart
+++ b/lib/src/package_config_io.dart
@@ -30,6 +30,13 @@
/// The file must exist and be a normal file.
Future<PackageConfig> readAnyConfigFile(
File file, bool preferNewest, void onError(Object error)) async {
+ if (preferNewest && fileName(file.path) == ".packages") {
+ var alternateFile =
+ File(pathJoin(dirName(file.path), ".dart_tool", "package_config.json"));
+ if (alternateFile.existsSync()) {
+ return await readPackageConfigJsonFile(alternateFile, onError);
+ }
+ }
Uint8List bytes;
try {
bytes = await file.readAsBytes();
@@ -37,28 +44,7 @@
onError(e);
return const SimplePackageConfig.empty();
}
- var firstChar = firstNonWhitespaceChar(bytes);
- if (firstChar != $lbrace) {
- // Definitely not a JSON object, probably a .packages.
- if (preferNewest) {
- var alternateFile = File(
- pathJoin(dirName(file.path), ".dart_tool", "package_config.json"));
- if (alternateFile.existsSync()) {
- Uint8List /*?*/ bytes;
- try {
- bytes = await alternateFile.readAsBytes();
- } catch (e) {
- onError(e);
- return const SimplePackageConfig.empty();
- }
- if (bytes != null) {
- return parsePackageConfigBytes(bytes, alternateFile.uri, onError);
- }
- }
- }
- return packages_file.parse(bytes, file.uri, onError);
- }
- return parsePackageConfigBytes(bytes, file.uri, onError);
+ return parseAnyConfigFile(bytes, file.uri, onError);
}
/// Like [readAnyConfigFile] but uses a URI and an optional loader.
@@ -73,11 +59,24 @@
}
if (loader == null) {
if (file.isScheme("file")) {
- return readAnyConfigFile(File.fromUri(file), preferNewest, onError);
+ return await readAnyConfigFile(File.fromUri(file), preferNewest, onError);
}
loader = defaultLoader;
}
- Uint8List bytes;
+ if (preferNewest && file.pathSegments.last == ".packages") {
+ var alternateFile = file.resolve(".dart_tool/package_config.json");
+ Uint8List /*?*/ bytes;
+ try {
+ bytes = await loader(alternateFile);
+ } catch (e) {
+ onError(e);
+ return const SimplePackageConfig.empty();
+ }
+ if (bytes != null) {
+ return parsePackageConfigBytes(bytes, alternateFile, onError);
+ }
+ }
+ Uint8List /*?*/ bytes;
try {
bytes = await loader(file);
} catch (e) {
@@ -89,23 +88,18 @@
file.toString(), "file", "File cannot be read"));
return const SimplePackageConfig.empty();
}
+ return parseAnyConfigFile(bytes, file, onError);
+}
+
+/// Parses a `.packages` or `package_config.json` file's contents.
+///
+/// Assumes it's a JSON file if the first non-whitespace character
+/// is `{`, otherwise assumes it's a `.packages` file.
+PackageConfig parseAnyConfigFile(
+ Uint8List bytes, Uri file, void onError(Object error)) {
var firstChar = firstNonWhitespaceChar(bytes);
if (firstChar != $lbrace) {
// Definitely not a JSON object, probably a .packages.
- if (preferNewest) {
- // Check if there is a package_config.json file.
- var alternateFile = file.resolveUri(packageConfigJsonPath);
- Uint8List alternateBytes;
- try {
- alternateBytes = await loader(alternateFile);
- } catch (e) {
- onError(e);
- return const SimplePackageConfig.empty();
- }
- if (alternateBytes != null) {
- return parsePackageConfigBytes(alternateBytes, alternateFile, onError);
- }
- }
return packages_file.parse(bytes, file, onError);
}
return parsePackageConfigBytes(bytes, file, onError);
diff --git a/lib/src/package_config_json.dart b/lib/src/package_config_json.dart
index b9b3416..27abf50 100644
--- a/lib/src/package_config_json.dart
+++ b/lib/src/package_config_json.dart
@@ -39,7 +39,7 @@
try {
jsonObject = _jsonUtf8Decoder.convert(bytes);
} on FormatException catch (e) {
- onError(PackageConfigFormatException(e.message, e.source, e.offset));
+ onError(PackageConfigFormatException.from(e));
return const SimplePackageConfig.empty();
}
return parsePackageConfigJson(jsonObject, file, onError);
@@ -51,7 +51,7 @@
try {
jsonObject = jsonDecode(source);
} on FormatException catch (e) {
- onError(PackageConfigFormatException(e.message, e.source, e.offset));
+ onError(PackageConfigFormatException.from(e));
return const SimplePackageConfig.empty();
}
return parsePackageConfigJson(jsonObject, file, onError);
@@ -271,7 +271,6 @@
}
}
packages_file.write(output, config, baseUri: baseUri, comment: comment);
- return;
}
/// If "extraData" is a JSON map, then return it, otherwise return null.
@@ -304,12 +303,10 @@
if (object == null || true == object || false == object) return true;
if (object is num || object is String) return true;
if (object is List<dynamic>) {
- for (var element in object) if (!_validateJson(element)) return false;
- return true;
+ return object.every(_validateJson);
}
if (object is Map<String, dynamic>) {
- for (var value in object.values) if (!_validateJson(value)) return false;
- return true;
+ return object.values.every(_validateJson);
}
return false;
}
diff --git a/lib/src/util_io.dart b/lib/src/util_io.dart
index 7f21a8d..2aa8c94 100644
--- a/lib/src/util_io.dart
+++ b/lib/src/util_io.dart
@@ -13,7 +13,7 @@
if (uri.isScheme("file")) {
var file = File.fromUri(uri);
try {
- return file.readAsBytes();
+ return await file.readAsBytes();
} catch (_) {
return null;
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 853c051..3f5ec27 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: package_config
-version: 1.9.1
+version: 1.9.2
description: Support for working with Package Configuration files.
homepage: https://github.com/dart-lang/package_config
diff --git a/test/discovery_test.dart b/test/discovery_test.dart
index 1a9a61c..5cbc992 100644
--- a/test/discovery_test.dart
+++ b/test/discovery_test.dart
@@ -301,13 +301,13 @@
});
// Find package_config.json in subdir even if initial file syntax error.
- fileTest("specified file syntax error", {
- "anyname": "syntax error",
+ fileTest("specified file syntax onError", {
+ ".packages": "syntax error",
".dart_tool": {
"package_config.json": packageConfigFile,
},
}, (Directory directory) async {
- var file = dirFile(directory, "anyname");
+ var file = dirFile(directory, ".packages");
var config = await loadPackageConfig(file);
expect(config.version, 2);
validatePackagesFile(config, directory);
diff --git a/test/discovery_uri_test.dart b/test/discovery_uri_test.dart
index 52fca3f..23c02d7 100644
--- a/test/discovery_uri_test.dart
+++ b/test/discovery_uri_test.dart
@@ -60,7 +60,7 @@
".dart_tool": {
"package_config.json": packageConfigFile,
}
- }, (Uri directory, loader) async {
+ }, (directory, loader) async {
var config = await findPackageConfigUri(directory, loader: loader);
expect(config.version, 2); // Found package_config.json file.
validatePackagesFile(config, directory);
@@ -71,7 +71,7 @@
".packages": packagesFile,
"script.dart": "main(){}",
"packages": {"shouldNotBeFound": {}}
- }, (Uri directory, loader) async {
+ }, (directory, loader) async {
var config = await findPackageConfigUri(directory, loader: loader);
expect(config.version, 1); // Found .packages file.
validatePackagesFile(config, directory);
@@ -86,7 +86,7 @@
"subdir": {
"script.dart": "main(){}",
}
- }, (Uri directory, loader) async {
+ }, (directory, loader) async {
var config = await findPackageConfigUri(directory.resolve("subdir/"),
loader: loader);
expect(config.version, 2);
@@ -97,7 +97,7 @@
loaderTest(".packages recursive", {
".packages": packagesFile,
"subdir": {"script.dart": "main(){}"}
- }, (Uri directory, loader) async {
+ }, (directory, loader) async {
var config;
config = await findPackageConfigUri(directory.resolve("subdir/"),
loader: loader);
@@ -240,9 +240,9 @@
throwsFormatException);
});
- loaderTest("specified file syntax error", {
+ loaderTest("specified file syntax onError", {
"anyname": "syntax error",
- }, (Uri directory, loader) async {
+ }, (directory, loader) async {
var file = directory.resolve("anyname");
var hadError = false;
await loadPackageConfigUri(file,
@@ -254,23 +254,22 @@
expect(hadError, true);
});
- // Find package_config.json in subdir even if initial file syntax error.
- loaderTest("specified file syntax error", {
+ // Don't look for package_config.json if original file not named .packages.
+ loaderTest("specified file syntax error with alternative", {
"anyname": "syntax error",
".dart_tool": {
"package_config.json": packageConfigFile,
},
- }, (Uri directory, loader) async {
+ }, (directory, loader) async {
var file = directory.resolve("anyname");
- var config = await loadPackageConfigUri(file, loader: loader);
- expect(config.version, 2);
- validatePackagesFile(config, directory);
+ expect(() => loadPackageConfigUri(file, loader: loader),
+ throwsFormatException);
});
// A file starting with `{` is a package_config.json file.
loaderTest("file syntax error with {", {
".packages": "{syntax error",
- }, (Uri directory, loader) async {
+ }, (directory, loader) async {
var file = directory.resolve(".packages");
var hadError = false;
await loadPackageConfigUri(file,