Skip to content

Commit

Permalink
feat(dynamite): introduce dynamite config to set ignore directives
Browse files Browse the repository at this point in the history
Signed-off-by: Nikolas Rimikis <[email protected]>
  • Loading branch information
Leptopoda committed Oct 25, 2023
1 parent 50f1466 commit 9320e4c
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 115 deletions.
2 changes: 1 addition & 1 deletion packages/dynamite/dynamite/lib/builder.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:build/build.dart';
import 'package:dynamite/dynamite.dart';

Builder openAPIBuilder(final BuilderOptions options) => OpenAPIBuilder();
Builder openAPIBuilder(final BuilderOptions options) => OpenAPIBuilder(options);
58 changes: 32 additions & 26 deletions packages/dynamite/dynamite/lib/src/builder/imports.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,35 @@ import 'package:code_builder/code_builder.dart';
import 'package:dynamite/src/builder/state.dart';
import 'package:path/path.dart' as p;

List<Spec> generateImports(final AssetId outputId, final State state) => [
const Code('// ignore_for_file: camel_case_types'),
const Code('// ignore_for_file: discarded_futures'),
const Code('// ignore_for_file: public_member_api_docs'),
const Code('// ignore_for_file: unreachable_switch_case'),
Directive.import('dart:convert'),
Directive.import('dart:typed_data'),
const Code(''),
Directive.import('package:built_collection/built_collection.dart'),
Directive.import('package:built_value/built_value.dart'),
Directive.import('package:built_value/json_object.dart'),
Directive.import('package:built_value/serializer.dart'),
Directive.import('package:built_value/standard_json_plugin.dart'),
Directive.import('package:collection/collection.dart'),
Directive.import('package:dynamite_runtime/built_value.dart'),
Directive.import('package:dynamite_runtime/http_client.dart'),
Directive.import('package:dynamite_runtime/models.dart'),
Directive.import('package:dynamite_runtime/utils.dart'),
Directive.import('package:meta/meta.dart'),
Directive.import('package:universal_io/io.dart'),
const Code(''),
if (state.resolvedTypes.isNotEmpty) ...[
Directive.part(p.basename(outputId.changeExtension('.g.dart').path)),
const Code(''),
],
];
Iterable<Spec> generateImports(final AssetId outputId, final State state) sync* {
final analyzerIgnores = state.buildConfig.analyzerIgnores;
if (analyzerIgnores != null) {
for (final rule in analyzerIgnores) {
yield Code('// ignore_for_file: $rule');
}
}

yield* [
Directive.import('dart:convert'),
Directive.import('dart:typed_data'),
const Code(''),
Directive.import('package:built_collection/built_collection.dart'),
Directive.import('package:built_value/built_value.dart'),
Directive.import('package:built_value/json_object.dart'),
Directive.import('package:built_value/serializer.dart'),
Directive.import('package:built_value/standard_json_plugin.dart'),
Directive.import('package:collection/collection.dart'),
Directive.import('package:dynamite_runtime/built_value.dart'),
Directive.import('package:dynamite_runtime/http_client.dart'),
Directive.import('package:dynamite_runtime/models.dart'),
Directive.import('package:dynamite_runtime/utils.dart'),
Directive.import('package:meta/meta.dart'),
Directive.import('package:universal_io/io.dart'),
const Code(''),
];

if (state.resolvedTypes.isNotEmpty) {
yield Directive.part(p.basename(outputId.changeExtension('.g.dart').path));
yield const Code('');
}
}
5 changes: 4 additions & 1 deletion packages/dynamite/dynamite/lib/src/builder/state.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import 'package:code_builder/code_builder.dart';
import 'package:dynamite/src/models/dynamite_config/config.dart';
import 'package:dynamite/src/models/type_result.dart';

class State {
State();
State(this.buildConfig);

final DynamiteConfig buildConfig;

final output = <Spec>[];
final resolvedTypes = <TypeResult>{};
Expand Down
1 change: 1 addition & 0 deletions packages/dynamite/dynamite/lib/src/models/config.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'dynamite_config/config.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';

part 'config.g.dart';

/// The configuration used by the dynamite builder.
abstract class DynamiteConfig implements Built<DynamiteConfig, DynamiteConfigBuilder> {
factory DynamiteConfig([final void Function(DynamiteConfigBuilder) updates]) = _$DynamiteConfig;

const DynamiteConfig._();

/// Constructs the dynamite config from a json like map.
factory DynamiteConfig.fromJson(final Map<String, dynamic> json) => _serializers.deserializeWith(_serializer, json)!;

/// Serializes this configuration to json.
Map<String, dynamic> toJson() => _serializers.serializeWith(_serializer, this)! as Map<String, dynamic>;

static Serializer<DynamiteConfig> get _serializer => _$dynamiteConfigSerializer;

static const String configPath = 'dynamite.yaml';

/// A set of lint rules to ignore for the entire generated file.
@BuiltValueField(wireName: 'analyzer_ignores')
BuiltSet<String>? get analyzerIgnores;

/// A set of regular expressions used to exclude parts from code coverage.
///
/// All matches will be wrapped in `// coverage:ignore-start` and `// coverage:ignore-end` blocs.
@BuiltValueField(wireName: 'coverage_ignores')
BuiltSet<String>? get coverageIgnores;
}

@SerializersFor([
DynamiteConfig,
])
final Serializers _serializers = (_$_serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();

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

42 changes: 21 additions & 21 deletions packages/dynamite/dynamite/lib/src/openapi_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,25 @@ import 'package:dynamite/src/builder/resolve_type.dart';
import 'package:dynamite/src/builder/serializer.dart';
import 'package:dynamite/src/builder/state.dart';
import 'package:dynamite/src/helpers/dart_helpers.dart';
import 'package:dynamite/src/models/config.dart';
import 'package:dynamite/src/models/openapi.dart' as openapi;
import 'package:dynamite/src/models/type_result.dart';
import 'package:version/version.dart';

class OpenAPIBuilder implements Builder {
OpenAPIBuilder(
final BuilderOptions options,
) : buildConfig = DynamiteConfig.fromJson(options.config);

@override
final buildExtensions = const {
'.openapi.json': ['.openapi.dart'],
'.openapi.yaml': ['.openapi.dart'],
};

/// The configuration for this builder.
final DynamiteConfig buildConfig;

@override
Future<void> build(final BuildStep buildStep) async {
try {
Expand Down Expand Up @@ -49,7 +57,7 @@ class OpenAPIBuilder implements Builder {
throw Exception('Only OpenAPI 3.0.0 and later are supported');
}

final state = State();
final state = State(buildConfig);

final output = ListBuilder<Spec>();

Expand Down Expand Up @@ -96,28 +104,20 @@ class OpenAPIBuilder implements Builder {
..addAll(state.output)
..addAll(serializer);

final patterns = [
RegExp(
r'const .*\._\(\);',
),
RegExp(
r'factory .*\.fromJson\(Map<String, dynamic> json\) => _jsonSerializers\.deserializeWith\(serializer, json\)!;',
),
RegExp(
r'Map<String, dynamic> toJson\(\) => _jsonSerializers\.serializeWith\(serializer, this\)! as Map<String, dynamic>;',
),
RegExp(
r'static BuiltSet<.*> get values => _\$.*Values;',
),
];

var outputString = output.build().map((final e) => e.accept(emitter)).join('\n');
for (final pattern in patterns) {
outputString = outputString.replaceAllMapped(
pattern,
(final match) => ' // coverage:ignore-start\n${match.group(0)}\n // coverage:ignore-end',
);

final coverageIgnores = state.buildConfig.coverageIgnores;
if (coverageIgnores != null) {
for (final ignore in coverageIgnores) {
final pattern = RegExp(ignore);

outputString = outputString.replaceAllMapped(
pattern,
(final match) => ' // coverage:ignore-start\n${match.group(0)}\n // coverage:ignore-end',
);
}
}

final formatter = DartFormatter(pageWidth: 120);
await buildStep.writeAsString(
outputId,
Expand Down
12 changes: 12 additions & 0 deletions packages/dynamite/dynamite_end_to_end_test/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
targets:
$default:
builders:
built_value_generator|built_value:
enabled: true
dynamite:
options:
analyzer_ignores:
- camel_case_types
- discarded_futures
- public_member_api_docs
- unreachable_switch_case
Loading

0 comments on commit 9320e4c

Please sign in to comment.