Match hosted shorthand syntax from Dart 2.15 (dart-lang/pubspec_parse#74)
* Match hosted shorthand syntax from Dart 2.15
diff --git a/pkgs/pubspec_parse/CHANGELOG.md b/pkgs/pubspec_parse/CHANGELOG.md
index 2601ee4..8f2d288 100644
--- a/pkgs/pubspec_parse/CHANGELOG.md
+++ b/pkgs/pubspec_parse/CHANGELOG.md
@@ -1,3 +1,12 @@
+## 1.2.0-dev
+
+- Update `HostedDetails` to reflect how `hosted` dependencies are parsed in
+ Dart 2.15:
+ - Add `HostedDetails.declaredName` as the (optional) `name` property in a
+ `hosted` block.
+ - `HostedDetails.name` now falls back to the name of the dependency if no
+ name is declared in the block.
+
## 1.1.1-dev
- Require Dart SDK >= 2.14.0
diff --git a/pkgs/pubspec_parse/lib/src/dependency.dart b/pkgs/pubspec_parse/lib/src/dependency.dart
index f8d3ecd..8b59f73 100644
--- a/pkgs/pubspec_parse/lib/src/dependency.dart
+++ b/pkgs/pubspec_parse/lib/src/dependency.dart
@@ -14,7 +14,7 @@
final key = k as String;
Dependency? value;
try {
- value = _fromJson(v);
+ value = _fromJson(v, k);
} on CheckedFromJsonException catch (e) {
if (e.map is! YamlMap) {
// This is likely a "synthetic" map created from a String value
@@ -40,7 +40,7 @@
const _sourceKeys = ['sdk', 'git', 'path', 'hosted'];
/// Returns `null` if the data could not be parsed.
-Dependency? _fromJson(Object? data) {
+Dependency? _fromJson(Object? data, String name) {
if (data is String || data == null) {
return _$HostedDependencyFromJson({'version': data});
}
@@ -82,7 +82,9 @@
case 'sdk':
return _$SdkDependencyFromJson(data);
case 'hosted':
- return _$HostedDependencyFromJson(data);
+ final hosted = _$HostedDependencyFromJson(data);
+ hosted.hosted?._nameOfPackage = name;
+ return hosted;
}
throw StateError('There is a bug in pubspec_parse.');
});
@@ -211,16 +213,30 @@
@JsonSerializable(disallowUnrecognizedKeys: true)
class HostedDetails {
- final String name;
+ /// The name of the target dependency as declared in a `hosted` block.
+ ///
+ /// This may be null if no explicit name is present, for instance because the
+ /// hosted dependency was declared as a string (`hosted: pub.example.org`).
+ @JsonKey(name: 'name')
+ final String? declaredName;
@JsonKey(fromJson: parseGitUriOrNull, disallowNullValue: true)
final Uri? url;
- HostedDetails(this.name, this.url);
+ @JsonKey(ignore: true)
+ String? _nameOfPackage;
+
+ /// The name of this package on the package repository.
+ ///
+ /// If this hosted block has a [declaredName], that one will be used.
+ /// Otherwise, the name will be inferred from the surrounding package name.
+ String get name => declaredName ?? _nameOfPackage!;
+
+ HostedDetails(this.declaredName, this.url);
factory HostedDetails.fromJson(Object data) {
if (data is String) {
- data = {'name': data};
+ data = {'url': data};
}
if (data is Map) {
diff --git a/pkgs/pubspec_parse/lib/src/dependency.g.dart b/pkgs/pubspec_parse/lib/src/dependency.g.dart
index 4e9d399..1a504f1 100644
--- a/pkgs/pubspec_parse/lib/src/dependency.g.dart
+++ b/pkgs/pubspec_parse/lib/src/dependency.g.dart
@@ -63,9 +63,10 @@
disallowNullValues: const ['url'],
);
final val = HostedDetails(
- $checkedConvert('name', (v) => v as String),
+ $checkedConvert('name', (v) => v as String?),
$checkedConvert('url', (v) => parseGitUriOrNull(v as String?)),
);
return val;
},
+ fieldKeyMap: const {'declaredName': 'name'},
);
diff --git a/pkgs/pubspec_parse/pubspec.yaml b/pkgs/pubspec_parse/pubspec.yaml
index d19201e..90ae1fe 100644
--- a/pkgs/pubspec_parse/pubspec.yaml
+++ b/pkgs/pubspec_parse/pubspec.yaml
@@ -2,7 +2,7 @@
description: >-
Simple package for parsing pubspec.yaml files with a type-safe API and rich
error reporting.
-version: 1.1.1-dev
+version: 1.2.0-dev
repository: https://github.com/dart-lang/pubspec_parse
environment:
diff --git a/pkgs/pubspec_parse/test/dependency_test.dart b/pkgs/pubspec_parse/test/dependency_test.dart
index 20053a8..da7badc 100644
--- a/pkgs/pubspec_parse/test/dependency_test.dart
+++ b/pkgs/pubspec_parse/test/dependency_test.dart
@@ -120,6 +120,21 @@
expect(dep.toString(), 'HostedDependency: ^1.0.0');
});
+ test('map /w hosted as a map without name', () {
+ final dep = _dependency<HostedDependency>(
+ {
+ 'version': '^1.0.0',
+ 'hosted': {'url': 'https://hosted_url'}
+ },
+ skipTryPub: true, // todo: Unskip once pub supports this syntax
+ );
+ expect(dep.version.toString(), '^1.0.0');
+ expect(dep.hosted!.declaredName, isNull);
+ expect(dep.hosted!.name, 'dep');
+ expect(dep.hosted!.url.toString(), 'https://hosted_url');
+ expect(dep.toString(), 'HostedDependency: ^1.0.0');
+ });
+
test('map w/ bad version value', () {
_expectThrows(
{
@@ -153,19 +168,22 @@
test('map w/ version and hosted as String', () {
final dep = _dependency<HostedDependency>(
- {'version': '^1.0.0', 'hosted': 'hosted_name'},
+ {'version': '^1.0.0', 'hosted': 'hosted_url'},
+ skipTryPub: true, // todo: Unskip once put supports this
);
expect(dep.version.toString(), '^1.0.0');
- expect(dep.hosted!.name, 'hosted_name');
- expect(dep.hosted!.url, isNull);
+ expect(dep.hosted!.declaredName, isNull);
+ expect(dep.hosted!.name, 'dep');
+ expect(dep.hosted!.url, Uri.parse('hosted_url'));
expect(dep.toString(), 'HostedDependency: ^1.0.0');
});
test('map w/ hosted as String', () {
- final dep = _dependency<HostedDependency>({'hosted': 'hosted_name'});
+ final dep = _dependency<HostedDependency>({'hosted': 'hosted_url'});
expect(dep.version, VersionConstraint.any);
- expect(dep.hosted!.name, 'hosted_name');
- expect(dep.hosted!.url, isNull);
+ expect(dep.hosted!.declaredName, isNull);
+ expect(dep.hosted!.name, 'dep');
+ expect(dep.hosted!.url, Uri.parse('hosted_url'));
expect(dep.toString(), 'HostedDependency: any');
});