mason
mason copied to clipboard
feat: Read a default configuration file by convention instead of configuration
Description
I have a brick that generates two files:
- page
- controller
To be able to share the brick across projects, I've added some variables:
- project_name
- page_id
- page_name
This works great, but when you are working on a project, the project_name
is for that project always the same. Asking the project_name
is redundant and error-prone.
So I've added a configuration file mason-variables.json
.
The Flutter project source is also generated using Mason, which means that this file is in my case always available and the content is specific for the generated Flutter project.
{
"project_name": "flutter_demo_app"
}
So now I can run:
mason make rubigo_page -c mason-variables.json
and now the brick only asks for
- page_id
- page_name
Is there a way that I can eliminate the need for adding -c mason-variables.json
to the mason command?
Of course, I could write a shell script, but that's not platform-independent. I also tried mason_hooks, but the pre_gen hook is executed after the variables are asked to the user.
A better idea might be to solve this by convention, for example, that a file with the name mason-variables.json
in the working directory is read by default by Mason.
Hi @jsroest š Thanks for opening an issue!
Can you please provide a bit more context?
Using the -c
flag is what Iād recommend in this case. Do you just not like specifying the path to the configuration file?
You should be able to use a pre_gen.dart hook to dynamically set the project name. You can remove the project name from vars in the brick.yaml and just use the hook to populate the variable.
Lastly, you can always create an alias for this if you want to type slightly slightly fewer characters.
Let me know what you think, thanks!
Hi,
Thanks for your quick reply.
Do you just not like specifying the path to the configuration file?
That's exactly the case.
Lastly, you can always create an alias for this if you want to type slightly fewer characters.
We have a mixed environment here, macOS and Windows. That would not be cross-platform.
You should be able to use a pre_gen.dart hook to dynamically set the project name. You can remove the project name from vars in the brick.yaml and just use the hook to populate the variable.
I've tried that.
This is the content of pre_gen.dart
:
import 'package:mason/mason.dart';
void run(HookContext context) {
// Read/Write vars
context.vars = {...context.vars, 'project_name': 'flutter_demo_app'};
// Use the logger
context.logger.info('hook says hi!');
}
The problem with that is the variable project_name
is still asked by Mason, and after that, overwritten by the pre_gen hook. This is confusing.
johannesroest@ws-z14 app % mason make rubigo_page
? What is the project name? this_will_be_overwritten
? What is the page id? s010
? What is the page name? ask_for_credentials
hook says hi!
ā Made brick rubigo_page (64ms)
ā Generated 2 file(s):
/Users/johannesroest/repos/1122334-flutter_demo_app/packages/app/lib/pages/s010_ask_for_credentials/s010_ask_for_credentials_controller.dart (identical)
/Users/johannesroest/repos/1122334-flutter_demo_app/packages/app/lib/pages/s010_ask_for_credentials/s010_ask_for_credentials_page.dart (identical)
This is the brick where you can find the {{project_name}}
.
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:{{project_name}}/pages/pages.dart';
import 'package:{{project_name}}/pages/{{#snakeCase}}{{page_id}}_{{page_name}}{{/snakeCase}}/{{#snakeCase}}{{page_id}}_{{page_name}}{{/snakeCase}}_controller.dart';
import 'package:rubigo_navigator/rubigo_navigator.dart';
class {{#pascalCase}}{{page_id}}{{/pascalCase}}{{#pascalCase}}{{page_name}}{{/pascalCase}}Page extends RubigoPage<Pages, {{#pascalCase}}{{page_id}}{{/pascalCase}}{{#pascalCase}}{{page_name}}{{/pascalCase}}Controller> {
const {{#pascalCase}}{{page_id}}{{/pascalCase}}{{#pascalCase}}{{page_name}}{{/pascalCase}}Page(ChangeNotifierProvider<{{#pascalCase}}{{page_id}}{{/pascalCase}}{{#pascalCase}}{{page_name}}{{/pascalCase}}Controller> controllerProvider,
{Key? key})
: super(controllerProvider, key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
title: const Text('{{#snakeCase}}{{page_id}}_{{page_name}}{{/snakeCase}}'),
),
body: Container(),
);
}
}
That's why it's great for my case if Mason loads a configuration file with a specific name, for example mason-variables.json
in the current folder by default. If the file is there, it will be read automatically, if the file is not there, Mason will ask for the variable.
It's not something that I can not live without, but it does streamline our use case.