Browse Source

Merge pull request #247 from provokateurin/feature/static-analysis-dynamite-output

Add dynamites output to static analysis to prevent mistakes
pull/249/head
Kate 2 years ago committed by GitHub
parent
commit
bb623818ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 44
      packages/dynamite/lib/src/openapi_builder.dart
  2. 4
      packages/nextcloud/analysis_options.yaml
  3. 1962
      packages/nextcloud/lib/src/nextcloud.openapi.dart
  4. 58
      packages/nextcloud/lib/src/nextcloud.openapi.g.dart
  5. 7
      tool/generate-nextcloud.sh

44
packages/dynamite/lib/src/openapi_builder.dart

@ -59,6 +59,9 @@ class OpenAPIBuilder implements Builder {
final state = State(prefix); final state = State(prefix);
final output = <String>[ final output = <String>[
'// ignore_for_file: avoid_dynamic_calls',
'// ignore_for_file: camel_case_types',
'// ignore_for_file: public_member_api_docs',
"import 'dart:convert';", "import 'dart:convert';",
"import 'dart:io';", "import 'dart:io';",
"import 'dart:typed_data';", "import 'dart:typed_data';",
@ -154,7 +157,7 @@ class OpenAPIBuilder implements Builder {
).accept(emitter).toString(), ).accept(emitter).toString(),
Class( Class(
(final b) => b (final b) => b
..name = '_Response' ..name = 'RawResponse'
..fields.addAll([ ..fields.addAll([
Field( Field(
(final b) => b (final b) => b
@ -197,7 +200,7 @@ class OpenAPIBuilder implements Builder {
..annotations.add(refer('override')) ..annotations.add(refer('override'))
..lambda = true ..lambda = true
..body = const Code( ..body = const Code(
r"'_Response(statusCode: $statusCode, headers: $headers, body: ${utf8.decode(body)})'", r"'RawResponse(statusCode: $statusCode, headers: $headers, body: ${utf8.decode(body)})'",
), ),
), ),
), ),
@ -205,7 +208,7 @@ class OpenAPIBuilder implements Builder {
Class( Class(
(final b) => b (final b) => b
..name = '${prefix}ApiException' ..name = '${prefix}ApiException'
..extend = refer('_Response') ..extend = refer('RawResponse')
..implements.add(refer('Exception')) ..implements.add(refer('Exception'))
..constructors.addAll( ..constructors.addAll(
[ [
@ -230,7 +233,7 @@ class OpenAPIBuilder implements Builder {
Parameter( Parameter(
(final b) => b (final b) => b
..name = 'response' ..name = 'response'
..type = refer('_Response'), ..type = refer('RawResponse'),
), ),
) )
..body = Code('${prefix}ApiException(response.statusCode, response.headers, response.body,)'), ..body = Code('${prefix}ApiException(response.statusCode, response.headers, response.body,)'),
@ -527,7 +530,7 @@ class OpenAPIBuilder implements Builder {
Method( Method(
(final b) => b (final b) => b
..name = 'doRequest' ..name = 'doRequest'
..returns = refer('Future<_Response>') ..returns = refer('Future<RawResponse>')
..modifier = MethodModifier.async ..modifier = MethodModifier.async
..requiredParameters.addAll([ ..requiredParameters.addAll([
Parameter( Parameter(
@ -572,7 +575,7 @@ class OpenAPIBuilder implements Builder {
response.headers.forEach((final name, final values) { response.headers.forEach((final name, final values) {
responseHeaders[name] = values.last; responseHeaders[name] = values.last;
}); });
return _Response( return RawResponse(
response.statusCode, response.statusCode,
responseHeaders, responseHeaders,
await response.bodyBytes, await response.bodyBytes,
@ -639,7 +642,12 @@ class OpenAPIBuilder implements Builder {
final parameters = <spec_parameter.Parameter>[ final parameters = <spec_parameter.Parameter>[
...pathParameters, ...pathParameters,
if (operation.parameters != null) ...operation.parameters!, if (operation.parameters != null) ...operation.parameters!,
]; ]..sort(
(final a, final b) => sortRequiredElements(
a.required ?? false,
b.required ?? false,
),
);
b b
..name = _toDartName(_filterMethodName(operationId, tag ?? '')) ..name = _toDartName(_filterMethodName(operationId, tag ?? ''))
..modifier = MethodModifier.async ..modifier = MethodModifier.async
@ -1231,6 +1239,13 @@ TypeResult resolveObject(
state.output.add( state.output.add(
Class( Class(
(final b) { (final b) {
final sortedParameterKeys = schema.properties!.keys.toList()
..sort(
(final a, final b) => sortRequiredElements(
(schema.required ?? []).contains(a),
(schema.required ?? []).contains(b),
),
);
b b
..name = '${state.prefix}$identifier' ..name = '${state.prefix}$identifier'
..docs.addAll(_descriptionToDocs(schema.description)) ..docs.addAll(_descriptionToDocs(schema.description))
@ -1254,7 +1269,7 @@ TypeResult resolveObject(
Constructor( Constructor(
(final b) => b (final b) => b
..optionalParameters.addAll( ..optionalParameters.addAll(
schema.properties!.keys.map( sortedParameterKeys.map(
(final propertyName) => Parameter( (final propertyName) => Parameter(
(final b) { (final b) {
final propertySchema = schema.properties![propertyName]!; final propertySchema = schema.properties![propertyName]!;
@ -1862,3 +1877,16 @@ TypeResult resolveType(
throw Exception('Can not convert OpenAPI type "${schema.toJson()}" to a Dart type'); throw Exception('Can not convert OpenAPI type "${schema.toJson()}" to a Dart type');
} }
// ignore: avoid_positional_boolean_parameters
int sortRequiredElements(final bool a, final bool b) {
if (a != b) {
if (a && !b) {
return -1;
} else {
return 1;
}
}
return 0;
}

4
packages/nextcloud/analysis_options.yaml

@ -1,5 +1 @@
include: package:nit_picking/dart.yaml include: package:nit_picking/dart.yaml
analyzer:
exclude:
- 'lib/src/**.openapi.**'

1962
packages/nextcloud/lib/src/nextcloud.openapi.dart

File diff suppressed because it is too large Load Diff

58
packages/nextcloud/lib/src/nextcloud.openapi.g.dart

@ -1270,16 +1270,9 @@ NextcloudNewsArticle _$NextcloudNewsArticleFromJson(Map<String, dynamic> json) {
id: json['id'] as int, id: json['id'] as int,
guid: json['guid'] as String, guid: json['guid'] as String,
guidHash: json['guidHash'] as String, guidHash: json['guidHash'] as String,
url: json['url'] as String?,
title: json['title'] as String, title: json['title'] as String,
author: json['author'] as String?,
pubDate: json['pubDate'] as int, pubDate: json['pubDate'] as int,
updatedDate: json['updatedDate'] as int?,
body: json['body'] as String, body: json['body'] as String,
enclosureMime: json['enclosureMime'] as String?,
enclosureLink: json['enclosureLink'] as String?,
mediaThumbnail: json['mediaThumbnail'] as String?,
mediaDescription: json['mediaDescription'] as String?,
feedId: json['feedId'] as int, feedId: json['feedId'] as int,
unread: json['unread'] as bool, unread: json['unread'] as bool,
starred: json['starred'] as bool, starred: json['starred'] as bool,
@ -1287,6 +1280,13 @@ NextcloudNewsArticle _$NextcloudNewsArticleFromJson(Map<String, dynamic> json) {
rtl: json['rtl'] as bool, rtl: json['rtl'] as bool,
fingerprint: json['fingerprint'] as String, fingerprint: json['fingerprint'] as String,
contentHash: json['contentHash'] as String, contentHash: json['contentHash'] as String,
url: json['url'] as String?,
author: json['author'] as String?,
updatedDate: json['updatedDate'] as int?,
enclosureMime: json['enclosureMime'] as String?,
enclosureLink: json['enclosureLink'] as String?,
mediaThumbnail: json['mediaThumbnail'] as String?,
mediaDescription: json['mediaDescription'] as String?,
); );
} }
@ -1336,17 +1336,17 @@ NextcloudNewsFeed _$NextcloudNewsFeedFromJson(Map<String, dynamic> json) {
id: json['id'] as int, id: json['id'] as int,
url: json['url'] as String, url: json['url'] as String,
title: json['title'] as String, title: json['title'] as String,
faviconLink: json['faviconLink'] as String?,
added: json['added'] as int, added: json['added'] as int,
folderId: json['folderId'] as int?,
unreadCount: json['unreadCount'] as int?,
ordering: json['ordering'] as int, ordering: json['ordering'] as int,
link: json['link'] as String?,
pinned: json['pinned'] as bool, pinned: json['pinned'] as bool,
updateErrorCount: json['updateErrorCount'] as int, updateErrorCount: json['updateErrorCount'] as int,
lastUpdateError: json['lastUpdateError'] as String?,
items: items:
(json['items'] as List<dynamic>).map((e) => NextcloudNewsArticle.fromJson(e as Map<String, dynamic>)).toList(), (json['items'] as List<dynamic>).map((e) => NextcloudNewsArticle.fromJson(e as Map<String, dynamic>)).toList(),
faviconLink: json['faviconLink'] as String?,
folderId: json['folderId'] as int?,
unreadCount: json['unreadCount'] as int?,
link: json['link'] as String?,
lastUpdateError: json['lastUpdateError'] as String?,
); );
} }
@ -1407,9 +1407,9 @@ NextcloudNewsListFeeds _$NextcloudNewsListFeedsFromJson(Map<String, dynamic> jso
allowedKeys: const ['starredCount', 'newestItemId', 'feeds'], allowedKeys: const ['starredCount', 'newestItemId', 'feeds'],
); );
return NextcloudNewsListFeeds( return NextcloudNewsListFeeds(
feeds: (json['feeds'] as List<dynamic>).map((e) => NextcloudNewsFeed.fromJson(e as Map<String, dynamic>)).toList(),
starredCount: json['starredCount'] as int?, starredCount: json['starredCount'] as int?,
newestItemId: json['newestItemId'] as int?, newestItemId: json['newestItemId'] as int?,
feeds: (json['feeds'] as List<dynamic>).map((e) => NextcloudNewsFeed.fromJson(e as Map<String, dynamic>)).toList(),
); );
} }
@ -1835,20 +1835,21 @@ NextcloudProvisioningApiUserDetails _$NextcloudProvisioningApiUserDetailsFromJso
], ],
); );
return NextcloudProvisioningApiUserDetails( return NextcloudProvisioningApiUserDetails(
enabled: json['enabled'] as bool?, displaynameScope: json['displaynameScope'] as String,
storageLocation: json['storageLocation'] as String?, backendCapabilities: NextcloudProvisioningApiUserDetails_BackendCapabilities.fromJson(
json['backendCapabilities'] as Map<String, dynamic>),
id: json['id'] as String, id: json['id'] as String,
lastLogin: json['lastLogin'] as int, lastLogin: json['lastLogin'] as int,
backend: json['backend'] as String, backend: json['backend'] as String,
subadmin: (json['subadmin'] as List<dynamic>).map((e) => e as String).toList(), subadmin: (json['subadmin'] as List<dynamic>).map((e) => e as String).toList(),
quota: NextcloudProvisioningApiUserDetails_Quota.fromJson(json['quota'] as Map<String, dynamic>), quota: NextcloudProvisioningApiUserDetails_Quota.fromJson(json['quota'] as Map<String, dynamic>),
avatarScope: json['avatarScope'] as String, avatarScope: json['avatarScope'] as String,
email: json['email'] as String?, locale: json['locale'] as String,
emailScope: json['emailScope'] as String, emailScope: json['emailScope'] as String,
additionalMail: (json['additional_mail'] as List<dynamic>).map((e) => e as String).toList(), additionalMail: (json['additional_mail'] as List<dynamic>).map((e) => e as String).toList(),
additionalMailScope: (json['additional_mailScope'] as List<dynamic>).map((e) => e as String).toList(), additionalMailScope: (json['additional_mailScope'] as List<dynamic>).map((e) => e as String).toList(),
displayname: json['displayname'] as String?, language: json['language'] as String,
displaynameScope: json['displaynameScope'] as String, groups: (json['groups'] as List<dynamic>).map((e) => e as String).toList(),
phone: json['phone'] as String, phone: json['phone'] as String,
phoneScope: json['phoneScope'] as String, phoneScope: json['phoneScope'] as String,
address: json['address'] as String, address: json['address'] as String,
@ -1860,7 +1861,7 @@ NextcloudProvisioningApiUserDetails _$NextcloudProvisioningApiUserDetailsFromJso
organisation: json['organisation'] as String, organisation: json['organisation'] as String,
organisationScope: json['organisationScope'] as String, organisationScope: json['organisationScope'] as String,
role: json['role'] as String, role: json['role'] as String,
roleScope: json['roleScope'] as String, fediverseScope: json['fediverseScope'] as String,
headline: json['headline'] as String, headline: json['headline'] as String,
headlineScope: json['headlineScope'] as String, headlineScope: json['headlineScope'] as String,
biography: json['biography'] as String, biography: json['biography'] as String,
@ -1868,13 +1869,12 @@ NextcloudProvisioningApiUserDetails _$NextcloudProvisioningApiUserDetailsFromJso
profileEnabled: json['profile_enabled'] as String, profileEnabled: json['profile_enabled'] as String,
profileEnabledScope: json['profile_enabledScope'] as String, profileEnabledScope: json['profile_enabledScope'] as String,
fediverse: json['fediverse'] as String, fediverse: json['fediverse'] as String,
fediverseScope: json['fediverseScope'] as String, roleScope: json['roleScope'] as String,
groups: (json['groups'] as List<dynamic>).map((e) => e as String).toList(), enabled: json['enabled'] as bool?,
language: json['language'] as String, displayname: json['displayname'] as String?,
locale: json['locale'] as String, email: json['email'] as String?,
notifyEmail: json['notify_email'] as String?, notifyEmail: json['notify_email'] as String?,
backendCapabilities: NextcloudProvisioningApiUserDetails_BackendCapabilities.fromJson( storageLocation: json['storageLocation'] as String?,
json['backendCapabilities'] as Map<String, dynamic>),
displayName: json['display-name'] as String?, displayName: json['display-name'] as String?,
); );
} }
@ -2211,10 +2211,10 @@ NextcloudUserStatusPublicStatus _$NextcloudUserStatusPublicStatusFromJson(Map<St
); );
return NextcloudUserStatusPublicStatus( return NextcloudUserStatusPublicStatus(
userId: json['userId'] as String, userId: json['userId'] as String,
status: $enumDecode(_$NextcloudUserStatusTypeEnumMap, json['status']),
message: json['message'] as String?, message: json['message'] as String?,
icon: json['icon'] as String?, icon: json['icon'] as String?,
clearAt: json['clearAt'] == null ? null : NextcloudUserStatusPublicStatus_ClearAt.fromJson(json['clearAt']), clearAt: json['clearAt'] == null ? null : NextcloudUserStatusPublicStatus_ClearAt.fromJson(json['clearAt']),
status: $enumDecode(_$NextcloudUserStatusTypeEnumMap, json['status']),
); );
} }
@ -2318,13 +2318,13 @@ NextcloudUserStatusStatus _$NextcloudUserStatusStatusFromJson(Map<String, dynami
); );
return NextcloudUserStatusStatus( return NextcloudUserStatusStatus(
userId: json['userId'] as String, userId: json['userId'] as String,
messageIsPredefined: json['messageIsPredefined'] as bool,
status: $enumDecode(_$NextcloudUserStatusTypeEnumMap, json['status']),
statusIsUserDefined: json['statusIsUserDefined'] as bool,
message: json['message'] as String?, message: json['message'] as String?,
messageId: json['messageId'] as String?, messageId: json['messageId'] as String?,
messageIsPredefined: json['messageIsPredefined'] as bool,
icon: json['icon'] as String?, icon: json['icon'] as String?,
clearAt: json['clearAt'] == null ? null : NextcloudUserStatusStatus_ClearAt.fromJson(json['clearAt']), clearAt: json['clearAt'] == null ? null : NextcloudUserStatusStatus_ClearAt.fromJson(json['clearAt']),
status: $enumDecode(_$NextcloudUserStatusTypeEnumMap, json['status']),
statusIsUserDefined: json['statusIsUserDefined'] as bool,
); );
} }

7
tool/generate-nextcloud.sh

@ -63,6 +63,9 @@ jq \
cd packages/nextcloud cd packages/nextcloud
rm -rf .dart_tool/build rm -rf .dart_tool/build
fvm dart pub run build_runner build --delete-conflicting-outputs fvm dart pub run build_runner build --delete-conflicting-outputs
# For some reason we need to fix and format twice, otherwise not everything gets fixed
fvm dart fix --apply lib/src/nextcloud.openapi.dart
../../tool/format.sh
fvm dart fix --apply lib/src/nextcloud.openapi.dart
../../tool/format.sh
) )
./tool/format.sh

Loading…
Cancel
Save