Proposal - Custom Script Support
Background
As a developer who creates/maintains bricks, it's fairly common to want to execute some code either before or after generation. Currently, the only way to achieve this is to use mason as a dependency and build a custom CLI that performs the pre/post generation tasks manually (very_good_cli is a great example of this).
Problem
The above limitation forces developers to write a lot of additional code and create wrappers on top of mason just to execute custom code before or after the generation process. If mason could support this natively, that would drastically improve the developer experience and reduce the amount of effort needed apply custom scripts. It would also improve the experience of the consumer because a brick could handle performing time-consuming tasks automatically on behalf of the user (see more in Use Cases).
Example Use Cases
If mason supported custom script execution before and/or after generation it would allow brick maintainers to support things like:
- pre generation input validation
- pre generation dynamic variable creation (things like UUIDs or timestamps)
- post generation dependency installation (
flutter packages get
)
- post generation formatting/fixes (
dart fix --apply
)
Real World Examples:
Proposed Usage
Bricks can include an optional hooks
directory with an optional pre_gen
and post_gen
script (Dart).
For example:
.
βββ __brick__
β βββ GREETINGS.md
βββ brick.yaml
βββ hooks
βββ post_gen.dart
where brick.yaml
looks like:
name: greeting
description: A Simple Greeting Template
vars:
- name
Mason would handle bundling the scripts as part of the brick and can execute the scripts at their respective times. In addition, the hooks themselves can contain templated variables. For example, in the post_gen.dart
script above we could have the following code
import 'dart:io';
void main() {
print('hello {{name}}!');
print(Directory.current.path);
}
The result of running mason make greeting --name
would be:
$ mason make greeting --name Dash
β Made brick greeting (0.0s)
β Generated 1 file:
/Users/dash/mason/example/GREETINGS.md (new)
hello Dash!
/Users/dash/mason/example
Note that the script was able to access template variables and the working directory of the script was the directory in which the code is generated.
Open Questions
Some open questions regarding the above proposal are:
- Should the custom scripts be executed by the mason cli or should the custom scripts also be executed automatically when a brick is generated programmatically via
MasonGenerator.fromBundle(...)
?
- Should a developer be able to disable custom script execution when using mason via the cli?
- Should mason be able to support external custom scripts?
- Are there any other hooks (besides
pre_gen
and post_gen
) that would be valuable to support?
- Should custom dart scripts have access to a
Logger
instance?
Additional Context
- Original feature request: #114