Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pkgs/pubspec_parse/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.6.0-wip

- Supports 'tag_pattern's via `GitDependency.tagPattern`.

## 1.5.0

- Added fields to `Pubspec`: `executables`, `resolution`, `workspace`.
Expand Down
70 changes: 55 additions & 15 deletions pkgs/pubspec_parse/lib/src/dependency.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Dependency? _fromJson(Object? data, String name) {
final key = matchedKeys.single;

return switch (key) {
'git' => GitDependency.fromData(data[key]),
'git' => GitDependency.fromJson(data),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I note that PathDependency - which also isn't generated via JsonSerializable - uses fromData instead of fromJson. Perhaps also appropriate for GitDependency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm Yeah - the difference is that fromData takes the descriptor only and throws away any version constraint (at least that was my interpretation).
For tag_pattern git dependencies, you need the version constraint to make any sense of it all.

'path' => PathDependency.fromData(data[key]),
'sdk' => _$SdkDependencyFromJson(data),
'hosted' => _$HostedDependencyFromJson(data)
Expand Down Expand Up @@ -112,25 +112,65 @@ class SdkDependency extends Dependency {
String toString() => 'SdkDependency: $sdk';
}

@JsonSerializable()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps add a line comment here explaining why we don't use json serializable here - that's it's deliberate (in order to have custom parsing in fromJson).

class GitDependency extends Dependency {
@JsonKey(fromJson: parseGitUri)
final Uri url;
final String? ref;
final String? path;

GitDependency(this.url, {this.ref, this.path});

factory GitDependency.fromData(Object? data) {
if (data is String) {
data = {'url': data};
}

if (data is Map) {
return _$GitDependencyFromJson(data);
}

throw ArgumentError.value(data, 'git', 'Must be a String or a Map.');
final String? tagPattern;
final VersionConstraint? version;

GitDependency(this.url, {this.ref, this.path, this.tagPattern, this.version});

factory GitDependency.fromJson(Map data) {
final version = switch (data['version']) {
final String? s => _constraintFromString(s),
_ => throw ArgumentError.value(
data['version'],
'version',
'if present must be a string.',
),
};
final gitData = switch (data['git']) {
final String s => {'url': s},
final Map m => m,
_ => throw ArgumentError.value(
data['git'],
'git',
'Must be a string or map.',
),
};
final url = switch (gitData['url']) {
final String s => parseGitUri(s),
_ =>
throw ArgumentError.value(gitData['url'], 'url', 'Must be a String.'),
};
final ref = switch (gitData['ref']) {
final String? s => s,
_ =>
throw ArgumentError.value(gitData['ref'], 'ref', 'Must be a String.'),
};
final path = switch (gitData['path']) {
final String? s => s,
_ =>
throw ArgumentError.value(gitData['path'], 'path', 'Must be a String.'),
};
final tagPattern = switch (gitData['tag_pattern']) {
final String? s => s,
_ => throw ArgumentError.value(
gitData['tag_pattern'],
'tag_pattern',
'Must be a String.',
),
};

return GitDependency(
url,
ref: ref,
path: path,
tagPattern: tagPattern,
version: version,
);
}

@override
Expand Down
13 changes: 0 additions & 13 deletions pkgs/pubspec_parse/lib/src/dependency.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkgs/pubspec_parse/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: pubspec_parse
version: 1.5.0
version: 1.6.0-wip
description: >-
Simple package for parsing pubspec.yaml files with a type-safe API and rich
error reporting.
Expand Down
32 changes: 26 additions & 6 deletions pkgs/pubspec_parse/test/dependency_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,25 @@ void _gitDependency() {
expect(dep.toString(), 'GitDependency: url@url');
});

test('tag_pattern works, and does not ignore version', () async {
final dep = await _dependency<GitDependency>(
{
'git': {
'url': 'url',
'tag_pattern': 'v{{version}}',
},
'version': '^1.2.3',
},
languageVersion: '3.9',
);
expect(dep.url.toString(), 'url');
expect(dep.path, isNull);
expect(dep.ref, isNull);
expect(dep.tagPattern, 'v{{version}}');
expect(dep.version.toString(), '^1.2.3');
expect(dep.toString(), 'GitDependency: url@url');
});

test('string with user@ URL', () async {
final skipTryParse = Platform.environment.containsKey('TRAVIS');
if (skipTryParse) {
Expand Down Expand Up @@ -299,7 +318,7 @@ line 6, column 4: Unrecognized keys: [bob]; supported keys: [sdk, git, path, hos
_expectThrows(
{'git': null},
r'''
line 5, column 11: Unsupported value for "git". Must be a String or a Map.
line 5, column 11: Unsupported value for "git". Must be a string or map.
5 │ "git": null
│ ┌───────────^
Expand All @@ -313,7 +332,7 @@ line 5, column 11: Unsupported value for "git". Must be a String or a Map.
_expectThrows(
{'git': 42},
r'''
line 5, column 11: Unsupported value for "git". Must be a String or a Map.
line 5, column 11: Unsupported value for "git". Must be a string or map.
5 │ "git": 42
│ ┌───────────^
Expand All @@ -326,7 +345,7 @@ line 5, column 11: Unsupported value for "git". Must be a String or a Map.
test('git - empty map', () {
_expectThrowsContaining(
{'git': <String, dynamic>{}},
r"type 'Null' is not a subtype of type 'String'",
r'Missing key "url". Must be a String',
);
});

Expand All @@ -335,7 +354,7 @@ line 5, column 11: Unsupported value for "git". Must be a String or a Map.
{
'git': {'url': null},
},
r"type 'Null' is not a subtype of type 'String'",
r'Missing key "url". Must be a String',
);
});

Expand All @@ -344,7 +363,7 @@ line 5, column 11: Unsupported value for "git". Must be a String or a Map.
{
'git': {'url': 42},
},
r"type 'int' is not a subtype of type 'String'",
r'Missing key "url". Must be a String',
);
});
}
Expand Down Expand Up @@ -428,10 +447,11 @@ void _expectThrowsContaining(Object content, String errorText) {
Future<T> _dependency<T extends Dependency>(
Object? content, {
bool skipTryPub = false,
String languageVersion = '2.12',
}) async {
final value = await parse(
{
...defaultPubspec,
...defaultPubspec(languageVersion: languageVersion),
'dependencies': {'dep': content},
},
skipTryPub: skipTryPub,
Expand Down
Loading