Skip to content

Commit

Permalink
feat: v0.0.1-dev.17
Browse files Browse the repository at this point in the history
  • Loading branch information
felangel committed Dec 2, 2020
1 parent 05ed3df commit 53526db
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 0.0.1-dev.17

- feat: support dart execution inside templates
- docs: add random_number example
- fix: handle empty or missing vars in `brick.yaml`

# 0.0.1-dev.16

- **BREAKING**: `mason make` creates subcommands for all available bricks
Expand Down
8 changes: 8 additions & 0 deletions bricks/random_number/__brick__/RANDOM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# {{name}}'s Lucky Number is

```dart
import 'dart:math';
void main(args, port) {
port.send('${Random().nextInt(9999)}');
}
```
4 changes: 4 additions & 0 deletions bricks/random_number/brick.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: random_number
description: A Simple Random Number Generator
vars:
- name
2 changes: 2 additions & 0 deletions example/mason.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ bricks:
path: ../bricks/documentation
greeting:
path: ../bricks/greeting
random_number:
path: ../bricks/random_number
todos:
path: ../bricks/todos
widget:
Expand Down
5 changes: 3 additions & 2 deletions lib/src/brick_yaml.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ part 'brick_yaml.g.dart';
@JsonSerializable()
class BrickYaml {
/// {@macro mason_yaml}
const BrickYaml(this.name, this.description, this.vars, {this.path});
const BrickYaml(this.name, this.description, {List<String> vars, this.path})
: vars = vars ?? const <String>[];

/// Converts [Map] to [BrickYaml]
factory BrickYaml.fromJson(Map<dynamic, dynamic> json) =>
Expand Down Expand Up @@ -41,6 +42,6 @@ class BrickYaml {
/// Returns a copy of the current [BrickYaml] with
/// an overridden [path].
BrickYaml copyWith({String path}) {
return BrickYaml(name, description, vars, path: path ?? this.path);
return BrickYaml(name, description, vars: vars, path: path ?? this.path);
}
}
2 changes: 1 addition & 1 deletion lib/src/brick_yaml.g.dart

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

42 changes: 37 additions & 5 deletions lib/src/generator.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io' show Directory, File;
import 'dart:isolate';

import 'package:http/http.dart' as http;
import 'package:path/path.dart' as p;
Expand All @@ -12,6 +13,8 @@ import 'mason_yaml.dart';
import 'render.dart';

final _fileRegExp = RegExp(r'<%\s?([a-zA-Z]+)\s?%>');
final _codeRegExp = RegExp(r'```dart(.*)```', dotAll: true);
final _codeReplaceRegExp = RegExp(r'(```dart(.*)```)', dotAll: true);

/// {@template mason_generator}
/// A [MasonGenerator] which extends [Generator] and
Expand Down Expand Up @@ -99,14 +102,25 @@ abstract class Generator implements Comparable<Generator> {
Map<String, dynamic> vars,
}) async {
await Future.forEach(files, (TemplateFile file) async {
final match = _fileRegExp.firstMatch(file.path);
if (match != null) {
final resultFile = await _fetch(vars[match[1]] as String);
final fileMatch = _fileRegExp.firstMatch(file.path);
if (fileMatch != null) {
final resultFile = await _fetch(vars[fileMatch[1]] as String);
return target.createFile(resultFile.path, resultFile.content);
} else {
final resultFile = file.runSubstitution(vars ?? <String, dynamic>{});
}

final codeMatch = _codeRegExp.firstMatch(file.content);
if (codeMatch != null) {
final result = await _exec(codeMatch[1]);
final newFile = TemplateFile(
file.path,
file.content.replaceFirst(_codeReplaceRegExp, result),
);
final resultFile = newFile.runSubstitution(vars ?? <String, dynamic>{});
return target.createFile(resultFile.path, resultFile.content);
}

final resultFile = file.runSubstitution(vars ?? <String, dynamic>{});
return target.createFile(resultFile.path, resultFile.content);
});
}

Expand All @@ -131,6 +145,19 @@ abstract class Generator implements Comparable<Generator> {
return FileContents(target, response.bodyBytes);
}
}

Future<String> _exec(String source) async {
final uri = _toDartDataUri(source);
RawReceivePort receivePort;
final completer = Completer<String>();
receivePort = RawReceivePort((String message) {
completer.complete(message);
receivePort.close();
});
await Isolate.spawnUri(uri, [], receivePort.sendPort);
final content = await completer.future;
return content;
}
}

/// {@template directory_generator_target}
Expand Down Expand Up @@ -207,3 +234,8 @@ class FileContents {
/// The contents of the file.
final List<int> content;
}

Uri _toDartDataUri(String source) {
return Uri.parse('data:application/dart;charset=utf-8,'
'${Uri.encodeComponent(source)}');
}
2 changes: 1 addition & 1 deletion lib/src/version.dart

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

2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: mason
description: >
A Dart template generator which helps teams generate files quickly and consistently.
version: 0.0.1-dev.16
version: 0.0.1-dev.17
homepage: https://github.com/felangel/mason

environment:
Expand Down

0 comments on commit 53526db

Please sign in to comment.