Skip to content

Commit

Permalink
pubspec_parse: Added support for executables field in pubspec.yaml (
Browse files Browse the repository at this point in the history
#1952)

Co-authored-by: Kevin Moore <[email protected]>
  • Loading branch information
Dhruv-Maradiya and kevmoo authored Jan 7, 2025
1 parent 5265a85 commit 070355e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 3 deletions.
4 changes: 2 additions & 2 deletions pkgs/pubspec_parse/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 1.5.0-wip
## 1.5.0

- Add `Pubspec.workspace` and `Pubspec.resolution` fields.
- Added fields to `Pubspec`: `executables`, `resolution`, `workspace`.
- Require Dart 3.6
- Update dependencies.

Expand Down
24 changes: 24 additions & 0 deletions pkgs/pubspec_parse/lib/src/pubspec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ class Pubspec {
/// and other settings.
final Map<String, dynamic>? flutter;

/// Optional field to specify executables
@JsonKey(fromJson: _executablesMap)
final Map<String, String?> executables;

/// If this package is a Pub Workspace, this field lists the sub-packages.
final List<String>? workspace;

Expand Down Expand Up @@ -129,12 +133,14 @@ class Pubspec {
Map<String, Dependency>? devDependencies,
Map<String, Dependency>? dependencyOverrides,
this.flutter,
Map<String, String?>? executables,
}) :
// ignore: deprecated_member_use_from_same_package
authors = _normalizeAuthors(author, authors),
environment = environment ?? const {},
dependencies = dependencies ?? const {},
devDependencies = devDependencies ?? const {},
executables = executables ?? const {},
dependencyOverrides = dependencyOverrides ?? const {} {
if (name.isEmpty) {
throw ArgumentError.value(name, 'name', '"name" cannot be empty.');
Expand Down Expand Up @@ -232,3 +238,21 @@ Map<String, VersionConstraint?> _environmentMap(Map? source) =>
return MapEntry(key, constraint);
}) ??
{};

Map<String, String?> _executablesMap(Map? source) =>
source?.map((k, value) {
final key = k as String;
if (value == null) {
return MapEntry(key, null);
} else if (value is String) {
return MapEntry(key, value);
} else {
throw CheckedFromJsonException(
source,
key,
'String',
'`$value` is not a String.',
);
}
}) ??
{};
2 changes: 2 additions & 0 deletions pkgs/pubspec_parse/lib/src/pubspec.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-wip
version: 1.5.0
description: >-
Simple package for parsing pubspec.yaml files with a type-safe API and rich
error reporting.
Expand Down
62 changes: 62 additions & 0 deletions pkgs/pubspec_parse/test/parse_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ void main() {
expect(value.screenshots, isEmpty);
expect(value.workspace, isNull);
expect(value.resolution, isNull);
expect(value.executables, isEmpty);
});

test('all fields set', () async {
Expand Down Expand Up @@ -64,6 +65,10 @@ void main() {
'pkg2',
],
'resolution': 'workspace',
'executables': {
'my_script': 'bin/my_script.dart',
'my_script2': 'bin/my_script2.dart',
},
},
skipTryPub: true,
);
Expand Down Expand Up @@ -96,6 +101,11 @@ void main() {
expect(value.screenshots, hasLength(1));
expect(value.screenshots!.first.description, 'my screenshot');
expect(value.screenshots!.first.path, 'path/to/screenshot');
expect(value.executables, hasLength(2));
expect(value.executables.keys, contains('my_script'));
expect(value.executables.keys, contains('my_script2'));
expect(value.executables['my_script'], 'bin/my_script.dart');
expect(value.executables['my_script2'], 'bin/my_script2.dart');
expect(value.workspace, hasLength(2));
expect(value.workspace!.first, 'pkg1');
expect(value.workspace!.last, 'pkg2');
Expand Down Expand Up @@ -222,6 +232,58 @@ line 3, column 16: Unsupported value for "publish_to". Must be an http or https
});
});

group('executables', () {
test('one executable', () async {
final value = await parse({
...defaultPubspec,
'executables': {'my_script': 'bin/my_script.dart'},
});
expect(value.executables, hasLength(1));
expect(value.executables.keys, contains('my_script'));
expect(value.executables['my_script'], 'bin/my_script.dart');
});

test('many executables', () async {
final value = await parse({
...defaultPubspec,
'executables': {
'my_script': 'bin/my_script.dart',
'my_script2': 'bin/my_script2.dart',
},
});
expect(value.executables, hasLength(2));
expect(value.executables.keys, contains('my_script'));
expect(value.executables.keys, contains('my_script2'));
expect(value.executables['my_script'], 'bin/my_script.dart');
expect(value.executables['my_script2'], 'bin/my_script2.dart');
});

test('invalid value', () async {
expectParseThrowsContaining(
{
...defaultPubspec,
'executables': {
'script': 32,
},
},
'Unsupported value for "script". `32` is not a String.',
skipTryPub: true,
);
});

test('invalid executable - lenient', () async {
final value = await parse(
{
...defaultPubspec,
'executables': 'Invalid value',
},
lenient: true,
);
expect(value.name, 'sample');
expect(value.executables, isEmpty);
});
});

group('invalid', () {
test('null', () {
expectParseThrows(
Expand Down

0 comments on commit 070355e

Please sign in to comment.