├── .github ├── CODEOWNERS ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── build.md │ ├── chore.md │ ├── ci.md │ ├── config.yml │ ├── documentation.md │ ├── feature_request.md │ ├── performance.md │ ├── refactor.md │ ├── revert.md │ ├── style.md │ └── test.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yaml └── workflows │ ├── ci.yaml │ ├── mason.yaml │ ├── mason_api.yaml │ ├── mason_cli.yaml │ ├── mason_logger.yaml │ └── vscode.yaml ├── .gitignore ├── .vscode └── launch.json ├── README.md ├── analysis_options.yaml ├── assets ├── mason_demo.gif ├── mason_full.png └── mason_logo.png ├── bricks ├── app_icon │ ├── __brick__ │ │ └── {{% url %}} │ └── brick.yaml ├── bio │ ├── __brick__ │ │ └── ABOUT.md │ └── brick.yaml ├── documentation │ ├── __brick__ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ └── README.md │ └── brick.yaml ├── favorite_color │ ├── __brick__ │ │ └── color.md │ └── brick.yaml ├── favorite_languages │ ├── __brick__ │ │ └── languages.md │ └── brick.yaml ├── flavors │ ├── __brick__ │ │ ├── README.md │ │ └── main_{{#flavors}}{{{.}}}{{ │ │ │ └── flavors}}.dart │ └── brick.yaml ├── greeting │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── __brick__ │ │ └── GREETINGS.md │ └── brick.yaml ├── hello │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── __brick__ │ │ └── HELLO.md │ └── brick.yaml ├── hello_world │ ├── __brick__ │ │ ├── HELLO.md │ │ ├── {{~ common_footer.md }} │ │ └── {{~ common_header.md }} │ └── brick.yaml ├── hooks │ ├── __brick__ │ │ └── hooks.md │ ├── brick.yaml │ └── hooks │ │ ├── post_gen.dart │ │ ├── pre_gen.dart │ │ └── pubspec.yaml ├── legacy │ ├── __brick__ │ │ └── GREETINGS.md │ └── brick.yaml ├── photos │ ├── __brick__ │ │ └── image.png │ └── brick.yaml ├── plugin │ ├── __brick__ │ │ ├── README.md │ │ ├── example │ │ │ ├── {{#android}}android.dart{{ │ │ │ │ └── android}} │ │ │ └── {{#ios}}ios.dart{{ │ │ │ │ └── ios}} │ │ ├── tests │ │ │ ├── {{#android}}android_tests.dart{{ │ │ │ │ └── android}} │ │ │ └── {{#ios}}ios_tests.dart{{ │ │ │ │ └── ios}} │ │ ├── {{#android}}android{{ │ │ │ └── android}} │ │ │ │ └── README.md │ │ ├── {{#android}}build.gradle{{ │ │ │ └── android}} │ │ ├── {{#ios}}Podfile{{ │ │ │ └── ios}} │ │ └── {{#ios}}ios{{ │ │ │ └── ios}} │ │ │ └── README.md │ └── brick.yaml ├── random_color │ ├── __brick__ │ │ └── color.md │ ├── brick.yaml │ └── hooks │ │ ├── post_gen.dart │ │ ├── pre_gen.dart │ │ └── pubspec.yaml ├── simple │ ├── __brick__ │ │ └── HELLO.md │ └── brick.yaml ├── todos │ ├── __brick__ │ │ ├── todos.md │ │ └── todos │ │ │ ├── {{#todos}}todo_{{#upperCase}}{{{todo}}}{{ │ │ │ └── upperCase}}_todo.md{{ │ │ │ │ └── todos}} │ │ │ └── {{#todos}}{{{todo}}}{{ │ │ │ └── todos}} │ │ │ └── developers │ │ │ └── {{#developers}}{{{name}}}{{ │ │ │ └── developers}} │ │ │ └── info.md │ └── brick.yaml └── widget │ ├── __brick__ │ └── {{name.snakeCase()}}.dart │ └── brick.yaml ├── cspell.config.yaml ├── extensions └── vscode │ ├── .eslintrc.json │ ├── .gitignore │ ├── .vscode │ ├── extensions.json │ ├── launch.json │ ├── settings.json │ └── tasks.json │ ├── .vscodeignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── assets │ └── logo.png │ ├── package-lock.json │ ├── package.json │ ├── schema │ ├── brick.yaml.schema.json │ └── mason.yaml.schema.json │ ├── src │ ├── commands │ │ ├── add-brick.ts │ │ ├── index.ts │ │ ├── init.ts │ │ ├── make-brick.ts │ │ ├── new-brick.ts │ │ └── remove-brick.ts │ ├── events │ │ ├── index.ts │ │ └── on-file-saved.ts │ ├── extension.ts │ ├── mason │ │ ├── get-brick-yaml.ts │ │ ├── index.ts │ │ ├── is-mason-installed.ts │ │ ├── mason-add.ts │ │ ├── mason-exec.ts │ │ ├── mason-get.ts │ │ ├── mason-init.ts │ │ ├── mason-make.ts │ │ ├── mason-new.ts │ │ └── mason-remove.ts │ └── utils │ │ ├── exec.ts │ │ ├── index.ts │ │ └── prompt-for-target-directory.ts │ ├── tsconfig.json │ └── webpack.config.js ├── packages ├── mason │ ├── .gitignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── build.yaml │ ├── coverage_badge.svg │ ├── example │ │ └── main.dart │ ├── lib │ │ ├── mason.dart │ │ └── src │ │ │ ├── brick.dart │ │ │ ├── brick_compatibility.dart │ │ │ ├── brick_yaml.dart │ │ │ ├── brick_yaml.g.dart │ │ │ ├── bricks_json.dart │ │ │ ├── bundler.dart │ │ │ ├── exception.dart │ │ │ ├── generator.dart │ │ │ ├── git.dart │ │ │ ├── hooks.dart │ │ │ ├── mason_bundle.dart │ │ │ ├── mason_bundle.g.dart │ │ │ ├── mason_lock_json.dart │ │ │ ├── mason_lock_json.g.dart │ │ │ ├── mason_yaml.dart │ │ │ ├── mason_yaml.g.dart │ │ │ ├── path.dart │ │ │ ├── recase.dart │ │ │ ├── render.dart │ │ │ ├── string_case_extensions.dart │ │ │ ├── version.dart │ │ │ └── yaml_encode.dart │ ├── pubspec.yaml │ ├── pubspec_overrides.yaml │ └── test │ │ ├── bricks │ │ ├── custom_registry │ │ │ └── brick.yaml │ │ ├── loop │ │ │ ├── __brick__ │ │ │ │ └── main_{{#values}}{{{.}}}{{ │ │ │ │ │ └── values}}.txt │ │ │ └── brick.yaml │ │ ├── nested_conditional │ │ │ ├── __brick__ │ │ │ │ └── {{#generate}}{{#snakeCase}}{{{name}}}{{ │ │ │ │ │ └── snakeCase}}.txt{{ │ │ │ │ │ └── generate}} │ │ │ └── brick.yaml │ │ └── no_registry │ │ │ └── brick.yaml │ │ ├── bundles │ │ ├── bundles.dart │ │ ├── greeting_bundle.dart │ │ ├── hooks_bundle.dart │ │ ├── photos_bundle.dart │ │ └── relative_imports_bundle.dart │ │ ├── fixtures │ │ ├── basic │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── post_gen.dart │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ ├── compile_exception │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ ├── dependency_install_failure │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ ├── empty │ │ │ └── brick.yaml │ │ ├── execution_exception │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ ├── hooks │ │ │ ├── __brick__ │ │ │ │ └── hooks.md │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── post_gen.dart │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ ├── long_run │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ ├── malformed_pubspec │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ ├── missing_run │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ ├── programmatic_usage │ │ │ └── main.dart │ │ ├── relative_imports │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── legacy │ │ │ │ ├── post_gen.dill │ │ │ │ └── pre_gen.dill │ │ │ │ ├── post_gen.dart │ │ │ │ ├── pre_gen.dart │ │ │ │ ├── pubspec.yaml │ │ │ │ └── src │ │ │ │ └── main.dart │ │ ├── run_exception │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ └── unicode_hook │ │ │ ├── __brick__ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ ├── pre_gen.dart │ │ │ └── pubspec.yaml │ │ └── src │ │ ├── brick_compatibility_test.dart │ │ ├── brick_yaml_test.dart │ │ ├── bricks_json_test.dart │ │ ├── bundler_test.dart │ │ ├── exception_test.dart │ │ ├── generator_test.dart │ │ ├── git_test.dart │ │ ├── hooks_test.dart │ │ ├── mason_bundle_test.dart │ │ ├── mason_lock_json_test.dart │ │ ├── mason_yaml_test.dart │ │ ├── render_test.dart │ │ ├── string_case_extensions_test.dart │ │ └── yaml_encode_test.dart ├── mason_api │ ├── .gitignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── build.yaml │ ├── coverage_badge.svg │ ├── example │ │ └── main.dart │ ├── lib │ │ ├── mason_api.dart │ │ └── src │ │ │ ├── jwt_decode.dart │ │ │ ├── mason_api.dart │ │ │ └── models │ │ │ ├── brick_search_result.dart │ │ │ ├── brick_search_result.g.dart │ │ │ ├── credentials.dart │ │ │ ├── credentials.g.dart │ │ │ ├── error_response.dart │ │ │ ├── error_response.g.dart │ │ │ ├── models.dart │ │ │ └── user.dart │ ├── pubspec.yaml │ └── test │ │ └── src │ │ ├── jwt_decode_test.dart │ │ └── mason_api_test.dart ├── mason_cli │ ├── .gitignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── README.zh.md │ ├── analysis_options.yaml │ ├── bin │ │ └── mason.dart │ ├── coverage_badge.svg │ ├── dart_test.yaml │ ├── example │ │ ├── README.md │ │ ├── mason.yaml │ │ └── todos.json │ ├── lib │ │ ├── mason_cli.dart │ │ └── src │ │ │ ├── command.dart │ │ │ ├── command_runner.dart │ │ │ ├── commands │ │ │ ├── add.dart │ │ │ ├── bundle.dart │ │ │ ├── cache.dart │ │ │ ├── commands.dart │ │ │ ├── get.dart │ │ │ ├── init.dart │ │ │ ├── list.dart │ │ │ ├── login.dart │ │ │ ├── logout.dart │ │ │ ├── make.dart │ │ │ ├── new.dart │ │ │ ├── publish.dart │ │ │ ├── remove.dart │ │ │ ├── search.dart │ │ │ ├── unbundle.dart │ │ │ ├── update.dart │ │ │ └── upgrade.dart │ │ │ ├── install_brick.dart │ │ │ └── version.dart │ ├── pubspec.yaml │ ├── pubspec_overrides.yaml │ └── test │ │ ├── bricks │ │ ├── array_no_choices │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ └── brick.yaml │ │ ├── compilation_error │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ ├── brick.yaml │ │ │ └── hooks │ │ │ │ ├── pre_gen.dart │ │ │ │ └── pubspec.yaml │ │ ├── custom_registry │ │ │ └── brick.yaml │ │ ├── enum_no_choices │ │ │ ├── __brick__ │ │ │ │ └── .gitkeep │ │ │ └── brick.yaml │ │ ├── invalid_registry │ │ │ └── brick.yaml │ │ └── no_registry │ │ │ └── brick.yaml │ │ ├── bundles │ │ ├── bundles.dart │ │ ├── greeting.bundle │ │ ├── greeting_bundle.dart │ │ ├── hooks_bundle.dart │ │ └── legacy_greeting_bundle.dart │ │ ├── commands │ │ ├── add_test.dart │ │ ├── bundle_test.dart │ │ ├── cache_test.dart │ │ ├── get_test.dart │ │ ├── init_test.dart │ │ ├── list_test.dart │ │ ├── login_test.dart │ │ ├── logout_test.dart │ │ ├── make_test.dart │ │ ├── new_test.dart │ │ ├── publish_test.dart │ │ ├── remove_test.dart │ │ ├── search_test.dart │ │ ├── unbundle_test.dart │ │ ├── update_test.dart │ │ └── upgrade_test.dart │ │ ├── ensure_build_test.dart │ │ ├── fixtures │ │ ├── add │ │ │ ├── greeting │ │ │ │ └── GREETINGS.md │ │ │ └── widget │ │ │ │ └── cat.dart │ │ ├── init │ │ │ └── mason.yaml │ │ ├── install │ │ │ ├── greeting │ │ │ │ └── GREETINGS.md │ │ │ └── widget │ │ │ │ └── cat.dart │ │ ├── make │ │ │ ├── app_icon │ │ │ │ └── c823e53b3a1a7b0d36a9.png │ │ │ ├── bio │ │ │ │ └── ABOUT.md │ │ │ ├── documentation │ │ │ │ ├── .gitignore │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENSE │ │ │ │ └── README.md │ │ │ ├── favorite_color │ │ │ │ └── color.md │ │ │ ├── favorite_languages │ │ │ │ └── languages.md │ │ │ ├── flavors │ │ │ │ ├── README.md │ │ │ │ ├── main_development.dart │ │ │ │ └── main_production.dart │ │ │ ├── greeting │ │ │ │ └── GREETINGS.md │ │ │ ├── hello_world │ │ │ │ └── HELLO.md │ │ │ ├── hooks │ │ │ │ ├── basic │ │ │ │ │ ├── .post_gen.txt │ │ │ │ │ ├── .pre_gen.txt │ │ │ │ │ └── hooks.md │ │ │ │ └── no_hooks │ │ │ │ │ └── hooks.md │ │ │ ├── mason.yaml │ │ │ ├── output_dir │ │ │ │ └── dir │ │ │ │ │ └── GREETINGS.md │ │ │ ├── plugin │ │ │ │ ├── android │ │ │ │ │ ├── README.md │ │ │ │ │ ├── android │ │ │ │ │ │ └── README.md │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── example │ │ │ │ │ │ └── android.dart │ │ │ │ │ └── tests │ │ │ │ │ │ └── android_tests.dart │ │ │ │ ├── android_ios │ │ │ │ │ ├── Podfile │ │ │ │ │ ├── README.md │ │ │ │ │ ├── android │ │ │ │ │ │ └── README.md │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── example │ │ │ │ │ │ ├── android.dart │ │ │ │ │ │ └── ios.dart │ │ │ │ │ ├── ios │ │ │ │ │ │ └── README.md │ │ │ │ │ └── tests │ │ │ │ │ │ ├── android_tests.dart │ │ │ │ │ │ └── ios_tests.dart │ │ │ │ ├── empty │ │ │ │ │ └── README.md │ │ │ │ └── ios │ │ │ │ │ ├── Podfile │ │ │ │ │ ├── README.md │ │ │ │ │ ├── example │ │ │ │ │ └── ios.dart │ │ │ │ │ ├── ios │ │ │ │ │ └── README.md │ │ │ │ │ └── tests │ │ │ │ │ └── ios_tests.dart │ │ │ ├── simple │ │ │ │ └── HELLO.md │ │ │ ├── todos.md │ │ │ ├── todos │ │ │ │ ├── todos.json │ │ │ │ ├── todos.md │ │ │ │ └── todos │ │ │ │ │ ├── Code │ │ │ │ │ └── developers │ │ │ │ │ │ ├── Alex │ │ │ │ │ │ └── info.md │ │ │ │ │ │ ├── Jen │ │ │ │ │ │ └── info.md │ │ │ │ │ │ └── Sam │ │ │ │ │ │ └── info.md │ │ │ │ │ ├── Eat │ │ │ │ │ └── developers │ │ │ │ │ │ ├── Alex │ │ │ │ │ │ └── info.md │ │ │ │ │ │ ├── Jen │ │ │ │ │ │ └── info.md │ │ │ │ │ │ └── Sam │ │ │ │ │ │ └── info.md │ │ │ │ │ ├── Sleep │ │ │ │ │ └── developers │ │ │ │ │ │ ├── Alex │ │ │ │ │ │ └── info.md │ │ │ │ │ │ ├── Jen │ │ │ │ │ │ └── info.md │ │ │ │ │ │ └── Sam │ │ │ │ │ │ └── info.md │ │ │ │ │ ├── todo_CODE_todo.md │ │ │ │ │ ├── todo_EAT_todo.md │ │ │ │ │ └── todo_SLEEP_todo.md │ │ │ └── widget │ │ │ │ └── my_widget.dart │ │ ├── new │ │ │ ├── custom │ │ │ │ └── bricks │ │ │ │ │ └── hello_world │ │ │ │ │ ├── CHANGELOG.md │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── README.md │ │ │ │ │ ├── __brick__ │ │ │ │ │ └── HELLO.md │ │ │ │ │ └── brick.yaml │ │ │ ├── hooks │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── __brick__ │ │ │ │ │ └── HELLO.md │ │ │ │ ├── brick.yaml │ │ │ │ └── hooks │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── post_gen.dart │ │ │ │ │ ├── pre_gen.dart │ │ │ │ │ └── pubspec.yaml │ │ │ └── simple │ │ │ │ └── hello_world │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── __brick__ │ │ │ │ └── HELLO.md │ │ │ │ └── brick.yaml │ │ └── unbundle │ │ │ ├── __brick__ │ │ │ └── GREETINGS.md │ │ │ └── brick.yaml │ │ ├── helpers │ │ ├── directories_deep_equal.dart │ │ ├── helpers.dart │ │ ├── override_print.dart │ │ └── set_up_testing_environment.dart │ │ ├── mason_generator_test.dart │ │ └── src │ │ ├── command_runner_test.dart │ │ ├── command_test.dart │ │ └── install_brick_test.dart └── mason_logger │ ├── .gitignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── coverage_badge.svg │ ├── example │ └── main.dart │ ├── lib │ ├── mason_logger.dart │ └── src │ │ ├── ansi.dart │ │ ├── ffi │ │ ├── terminal.dart │ │ ├── unix_terminal.dart │ │ └── windows_terminal.dart │ │ ├── io.dart │ │ ├── level.dart │ │ ├── link.dart │ │ ├── mason_logger.dart │ │ ├── progress.dart │ │ └── terminal_overrides.dart │ ├── pubspec.yaml │ └── test │ ├── ci.dart │ ├── fixtures │ └── ci.txt │ └── src │ ├── io_test.dart │ ├── link_test.dart │ ├── mason_logger_test.dart │ ├── progress_test.dart │ └── terminal_overrides_test.dart └── tool └── verify_pub_score.sh /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Every request must be reviewed and accepted by: 2 | 3 | * @felangel -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [felangel] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a report to help us improve 4 | title: "fix: " 5 | labels: bug 6 | --- 7 | 8 | **Description** 9 | 10 | A clear and concise description of what the bug is. 11 | 12 | **Steps To Reproduce** 13 | 14 | 1. Go to '...' 15 | 2. Click on '....' 16 | 3. Scroll down to '....' 17 | 4. See error 18 | 19 | **Expected Behavior** 20 | 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Additional Context** 28 | 29 | Add any other context about the problem here. 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/build.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Build System 3 | about: Changes that affect the build system or external dependencies 4 | title: "build: " 5 | labels: build 6 | --- 7 | 8 | **Description** 9 | 10 | Describe what changes need to be done to the build system and why. 11 | 12 | **Requirements** 13 | 14 | - [ ] The build system is passing 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/chore.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Chore 3 | about: Other changes that don't modify src or test files 4 | title: "chore: " 5 | labels: chore 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what change is needed and why. If this changes code then please use another issue type. 11 | 12 | **Requirements** 13 | 14 | - [ ] No functional changes to the code 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ci.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Continuous Integration 3 | about: Changes to the CI configuration files and scripts 4 | title: "ci: " 5 | labels: ci 6 | --- 7 | 8 | **Description** 9 | 10 | Describe what changes need to be done to the ci/cd system and why. 11 | 12 | **Requirements** 13 | 14 | - [ ] The ci system is passing 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation 3 | about: Improve the documentation so all collaborators have a common understanding 4 | title: "docs: " 5 | labels: documentation 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what documentation you are looking to add or improve. 11 | 12 | **Requirements** 13 | 14 | - [ ] Requirements go here 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: A new feature to be added to the project 4 | title: "feat: " 5 | labels: feature 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what you are looking to add. The more context the better. 11 | 12 | **Requirements** 13 | 14 | - [ ] Checklist of requirements to be fulfilled 15 | 16 | **Additional Context** 17 | 18 | Add any other context or screenshots about the feature request go here. 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/performance.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Performance Update 3 | about: A code change that improves performance 4 | title: "perf: " 5 | labels: performance 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what code needs to be changed and what the performance impact is going to be. Bonus point's if you can tie this directly to user experience. 11 | 12 | **Requirements** 13 | 14 | - [ ] There is no drop in test coverage. 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/refactor.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Refactor 3 | about: A code change that neither fixes a bug nor adds a feature 4 | title: "refactor: " 5 | labels: refactor 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what needs to be refactored and why. Please provide links to related issues (bugs or upcoming features) in order to help prioritize. 11 | 12 | **Requirements** 13 | 14 | - [ ] There is no drop in test coverage. 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/revert.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Revert Commit 3 | about: Reverts a previous commit 4 | title: "revert: " 5 | labels: revert 6 | --- 7 | 8 | **Description** 9 | 10 | Provide a link to a PR/Commit that you are looking to revert and why. 11 | 12 | **Requirements** 13 | 14 | - [ ] Change has been reverted 15 | - [ ] No change in test coverage has happened 16 | - [ ] A new ticket is created for any follow on work that needs to happen 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/style.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Style Changes 3 | about: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) 4 | title: "style: " 5 | labels: style 6 | --- 7 | 8 | **Description** 9 | 10 | Clearly describe what you are looking to change and why. 11 | 12 | **Requirements** 13 | 14 | - [ ] There is no drop in test coverage. 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/test.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Test 3 | about: Adding missing tests or correcting existing tests 4 | title: "test: " 5 | labels: test 6 | --- 7 | 8 | **Description** 9 | 10 | List out the tests that need to be added or changed. Please also include any information as to why this was not covered in the past. 11 | 12 | **Requirements** 13 | 14 | - [ ] There is no drop in test coverage. 15 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ## Status 10 | 11 | **READY/IN DEVELOPMENT/HOLD** 12 | 13 | ## Description 14 | 15 | 16 | 17 | ## Type of Change 18 | 19 | 20 | 21 | - [ ] ✨ New feature (non-breaking change which adds functionality) 22 | - [ ] 🛠️ Bug fix (non-breaking change which fixes an issue) 23 | - [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change) 24 | - [ ] 🧹 Code refactor 25 | - [ ] ✅ Build configuration change 26 | - [ ] 📝 Documentation 27 | - [ ] 🗑️ Chore 28 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | groups: 8 | github_actions: 9 | patterns: 10 | - "*" 11 | - package-ecosystem: "pub" 12 | directory: "/packages/mason_cli" 13 | schedule: 14 | interval: "daily" 15 | groups: 16 | mason_cli: 17 | patterns: 18 | - "*" 19 | - package-ecosystem: "pub" 20 | directory: "/packages/mason_logger" 21 | schedule: 22 | interval: "daily" 23 | groups: 24 | mason_logger: 25 | patterns: 26 | - "*" 27 | - package-ecosystem: "pub" 28 | directory: "/packages/mason" 29 | schedule: 30 | interval: "daily" 31 | groups: 32 | mason: 33 | patterns: 34 | - "*" 35 | - package-ecosystem: "pub" 36 | directory: "/packages/mason_api" 37 | schedule: 38 | interval: "daily" 39 | groups: 40 | mason_api: 41 | patterns: 42 | - "*" 43 | - package-ecosystem: "npm" 44 | directory: "/extensions/vscode" 45 | schedule: 46 | interval: "daily" 47 | groups: 48 | vscode: 49 | patterns: 50 | - "*" 51 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | pull_request: 9 | branches: 10 | - master 11 | 12 | jobs: 13 | build: 14 | uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/semantic_pull_request.yml@v1 15 | 16 | pana: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: noop 20 | run: echo 'noop' -------------------------------------------------------------------------------- /.github/workflows/mason.yaml: -------------------------------------------------------------------------------- 1 | name: mason 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | push: 9 | branches: 10 | - master 11 | paths: 12 | - .github/workflows/mason.yaml 13 | - packages/mason_logger/** 14 | - packages/mason/** 15 | 16 | pull_request: 17 | branches: 18 | - master 19 | paths: 20 | - .github/workflows/mason.yaml 21 | - packages/mason_logger/** 22 | - packages/mason/** 23 | 24 | jobs: 25 | setup: 26 | defaults: 27 | run: 28 | working-directory: packages/mason 29 | 30 | runs-on: ubuntu-latest 31 | 32 | steps: 33 | - uses: actions/checkout@v4.2.2 34 | - uses: dart-lang/setup-dart@v1 35 | 36 | - name: Install Dependencies 37 | run: dart pub get 38 | 39 | - name: Format 40 | run: dart format --set-exit-if-changed lib 41 | 42 | - name: Analyze 43 | run: dart analyze --fatal-infos --fatal-warnings . 44 | 45 | build: 46 | needs: setup 47 | 48 | defaults: 49 | run: 50 | working-directory: packages/mason 51 | 52 | runs-on: ${{ matrix.os }} 53 | 54 | strategy: 55 | fail-fast: false 56 | matrix: 57 | os: [macos-latest, windows-2019, ubuntu-latest] 58 | 59 | steps: 60 | - uses: actions/checkout@v4.2.2 61 | - uses: dart-lang/setup-dart@v1 62 | 63 | - name: Install Dependencies 64 | run: dart pub get 65 | 66 | - name: Run Tests 67 | run: | 68 | dart pub global activate coverage 1.2.0 69 | dart test --timeout 2x -j 1 -x pull-request-only --coverage=coverage && dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.dart_tool/package_config.json --report-on=lib 70 | 71 | - name: Check Code Coverage 72 | uses: VeryGoodOpenSource/very_good_coverage@v3 73 | with: 74 | path: packages/mason/coverage/lcov.info 75 | 76 | pana: 77 | defaults: 78 | run: 79 | working-directory: packages/mason 80 | 81 | runs-on: ubuntu-latest 82 | 83 | steps: 84 | - uses: actions/checkout@v4.2.2 85 | - uses: dart-lang/setup-dart@v1 86 | 87 | - name: Install Dependencies 88 | run: | 89 | dart pub get 90 | dart pub global activate pana 91 | 92 | - name: Verify Pub Score 93 | run: ../../tool/verify_pub_score.sh 150 94 | -------------------------------------------------------------------------------- /.github/workflows/mason_api.yaml: -------------------------------------------------------------------------------- 1 | name: mason_api 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | push: 9 | branches: 10 | - master 11 | paths: 12 | - .github/workflows/mason_api.yaml 13 | - packages/mason_api/** 14 | 15 | pull_request: 16 | branches: 17 | - master 18 | paths: 19 | - .github/workflows/mason_api.yaml 20 | - packages/mason_api/** 21 | 22 | jobs: 23 | build: 24 | defaults: 25 | run: 26 | working-directory: packages/mason_api 27 | 28 | runs-on: ubuntu-latest 29 | 30 | steps: 31 | - uses: actions/checkout@v4.2.2 32 | - uses: dart-lang/setup-dart@v1 33 | 34 | - name: Install Dependencies 35 | run: dart pub get 36 | 37 | - name: Format 38 | run: dart format --set-exit-if-changed lib 39 | 40 | - name: Analyze 41 | run: dart analyze --fatal-infos --fatal-warnings . 42 | 43 | - name: Run Tests 44 | run: | 45 | dart pub global activate coverage 1.2.0 46 | dart test --coverage=coverage && dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.dart_tool/package_config.json --report-on=lib 47 | 48 | - name: Check Code Coverage 49 | uses: VeryGoodOpenSource/very_good_coverage@v3 50 | with: 51 | path: packages/mason_api/coverage/lcov.info 52 | 53 | pana: 54 | defaults: 55 | run: 56 | working-directory: packages/mason_api 57 | 58 | runs-on: ubuntu-latest 59 | 60 | steps: 61 | - uses: actions/checkout@v4.2.2 62 | - uses: dart-lang/setup-dart@v1 63 | 64 | - name: Install Dependencies 65 | run: | 66 | dart pub get 67 | dart pub global activate pana 68 | 69 | - name: Verify Pub Score 70 | run: ../../tool/verify_pub_score.sh 71 | -------------------------------------------------------------------------------- /.github/workflows/vscode.yaml: -------------------------------------------------------------------------------- 1 | name: vscode 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | push: 9 | branches: 10 | - master 11 | paths: 12 | - .github/workflows/vscode.yaml 13 | - extensions/vscode/** 14 | 15 | pull_request: 16 | branches: 17 | - master 18 | paths: 19 | - .github/workflows/vscode.yaml 20 | - extensions/vscode/** 21 | 22 | jobs: 23 | build: 24 | defaults: 25 | run: 26 | working-directory: extensions/vscode 27 | 28 | runs-on: ubuntu-latest 29 | 30 | steps: 31 | - uses: actions/checkout@v4.2.2 32 | 33 | - name: Setup node 34 | uses: actions/setup-node@v4 35 | 36 | - name: Install Dependencies 37 | run: npm install 38 | 39 | - name: Check Format 40 | run: npm run format:check 41 | 42 | - name: Lint 43 | run: npm run lint 44 | 45 | - name: Build 46 | run: npm run compile 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | # Remove the following pattern if you wish to check in your lock file 5 | pubspec.lock 6 | 7 | # Local Mason Files 8 | .mason/ 9 | build/ 10 | 11 | # IntelliJ and Android Studio 12 | .idea/ 13 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "mason", 9 | "request": "launch", 10 | "type": "dart", 11 | "program": "bin/mason.dart", 12 | "args": [] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /assets/mason_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/assets/mason_demo.gif -------------------------------------------------------------------------------- /assets/mason_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/assets/mason_full.png -------------------------------------------------------------------------------- /assets/mason_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/assets/mason_logo.png -------------------------------------------------------------------------------- /bricks/app_icon/__brick__/{{% url %}}: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/bricks/app_icon/__brick__/{{% url %}} -------------------------------------------------------------------------------- /bricks/app_icon/brick.yaml: -------------------------------------------------------------------------------- 1 | name: app_icon 2 | description: Create an app icon file from a URL 3 | version: 0.1.0+1 4 | vars: 5 | url: 6 | type: string 7 | description: The app icon URL. 8 | prompt: Enter your app icon URL. 9 | -------------------------------------------------------------------------------- /bricks/bio/__brick__/ABOUT.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Hello, my name is {{name}}! I am {{age}} years old and I {{#isDeveloper}}am{{/isDeveloper}}{{^isDeveloper}}am not{{/isDeveloper}} a developer. -------------------------------------------------------------------------------- /bricks/bio/brick.yaml: -------------------------------------------------------------------------------- 1 | name: bio 2 | description: A Bio Template 3 | version: 0.1.0+1 4 | vars: 5 | name: 6 | type: string 7 | description: Name of the current user 8 | default: Dash 9 | prompt: What is your name? 10 | age: 11 | type: number 12 | description: Age of the current user 13 | default: 42 14 | prompt: How old are you? 15 | isDeveloper: 16 | type: boolean 17 | description: If the current user is a developer 18 | default: false 19 | prompt: Are you a developer? -------------------------------------------------------------------------------- /bricks/documentation/__brick__/.gitignore: -------------------------------------------------------------------------------- 1 | # Temporary Files 2 | .tmp/ -------------------------------------------------------------------------------- /bricks/documentation/__brick__/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.0.0 2 | 3 | - initial release 🎉 -------------------------------------------------------------------------------- /bricks/documentation/__brick__/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2020 {{author}} 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without restriction, 7 | including without limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of the Software, 9 | and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 | USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /bricks/documentation/__brick__/README.md: -------------------------------------------------------------------------------- 1 | # {{name}} 💙 2 | 3 | {{description}} 4 | 5 | ## Usage 🚀 6 | 7 | ```sh 8 | # {{#titleCase}}{{name}}{{/titleCase}} 9 | ``` 10 | 11 | ``` 12 | ├── foo 13 | │ ├── bar 14 | │ │ ├── baz 15 | │ │ └── baz 16 | ``` 17 | -------------------------------------------------------------------------------- /bricks/documentation/brick.yaml: -------------------------------------------------------------------------------- 1 | name: documentation 2 | description: Create Documentation Markdown Files 3 | version: 0.1.0+1 4 | vars: 5 | name: 6 | type: string 7 | description: The name of the project 8 | default: Example 9 | prompt: What is the project name? 10 | description: 11 | type: string 12 | description: A short description of the project 13 | default: null 14 | prompt: What is the project description? 15 | author: 16 | type: string 17 | description: The name of the project author 18 | default: Dash 19 | prompt: Who is the project author? -------------------------------------------------------------------------------- /bricks/favorite_color/__brick__/color.md: -------------------------------------------------------------------------------- 1 | Your favorite color is {{color}}! 2 | -------------------------------------------------------------------------------- /bricks/favorite_color/brick.yaml: -------------------------------------------------------------------------------- 1 | name: favorite_color 2 | description: A new brick created with the Mason CLI. 3 | 4 | version: 0.1.0+1 5 | 6 | environment: 7 | mason: ^0.1.0 8 | 9 | vars: 10 | color: 11 | type: enum 12 | description: Your favorite color 13 | default: green 14 | prompt: What is your favorite color? 15 | values: 16 | - red 17 | - green 18 | - blue 19 | -------------------------------------------------------------------------------- /bricks/favorite_languages/__brick__/languages.md: -------------------------------------------------------------------------------- 1 | Your favorite languages are: 2 | {{#languages}}- {{.}} 3 | {{/languages}} -------------------------------------------------------------------------------- /bricks/favorite_languages/brick.yaml: -------------------------------------------------------------------------------- 1 | name: favorite_languages 2 | description: A new brick created with the Mason CLI. 3 | 4 | version: 0.1.0+1 5 | 6 | environment: 7 | mason: ^0.1.0 8 | 9 | vars: 10 | languages: 11 | type: list 12 | description: Your favorite languages 13 | prompt: What are your favorite languages? 14 | -------------------------------------------------------------------------------- /bricks/flavors/__brick__/README.md: -------------------------------------------------------------------------------- 1 | This project supports the following flavors: 2 | {{#flavors}} 3 | - {{.}}{{/flavors}} -------------------------------------------------------------------------------- /bricks/flavors/__brick__/main_{{#flavors}}{{{.}}}{{/flavors}}.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | {{#flavors}}print('Running in {{.}} mode...');{{/flavors}} 3 | } -------------------------------------------------------------------------------- /bricks/flavors/brick.yaml: -------------------------------------------------------------------------------- 1 | name: flavors 2 | description: A new brick created with the Mason CLI. 3 | 4 | version: 0.1.0+1 5 | 6 | environment: 7 | mason: ^0.1.0 8 | 9 | vars: 10 | flavors: 11 | type: array 12 | description: Supported flavors 13 | prompt: What flavors would you like to generate? 14 | defaults: 15 | - development 16 | - production 17 | values: 18 | - development 19 | - integration 20 | - staging 21 | - production 22 | -------------------------------------------------------------------------------- /bricks/greeting/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.1.0+1 2 | 3 | - TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /bricks/greeting/LICENSE: -------------------------------------------------------------------------------- 1 | TODO: Add your license here. 2 | -------------------------------------------------------------------------------- /bricks/greeting/README.md: -------------------------------------------------------------------------------- 1 | # greeting 2 | 3 | A new brick created with the Mason CLI. 4 | 5 | _Generated by [mason][1] 🧱_ 6 | 7 | ## Getting Started 🚀 8 | 9 | This is a starting point for a new brick. 10 | A few resources to get you started if this is your first brick template: 11 | 12 | - [Official Mason Documentation][2] 13 | - [Code generation with Mason Blog][3] 14 | - [Very Good Livestream: Felix Angelov Demos Mason][4] 15 | 16 | [1]: https://github.com/felangel/mason 17 | [2]: https://github.com/felangel/mason/tree/master/packages/mason_cli#readme 18 | [3]: https://verygood.ventures/blog/code-generation-with-mason 19 | [4]: https://youtu.be/G4PTjA6tpTU 20 | -------------------------------------------------------------------------------- /bricks/greeting/__brick__/GREETINGS.md: -------------------------------------------------------------------------------- 1 | Hi {{name}}! -------------------------------------------------------------------------------- /bricks/greeting/brick.yaml: -------------------------------------------------------------------------------- 1 | name: greeting 2 | description: A Simple Greeting Template 3 | repository: https://github.com/felangel/mason/tree/master/bricks/greeting 4 | version: 0.1.0+1 5 | vars: 6 | name: 7 | type: string 8 | description: Your name 9 | default: Dash 10 | prompt: What is your name? 11 | -------------------------------------------------------------------------------- /bricks/hello/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.1.0+2 2 | 3 | - chore: upgrade to `mason ^0.1.0` 4 | 5 | # 0.1.0+1 6 | 7 | - chore: initial release 8 | -------------------------------------------------------------------------------- /bricks/hello/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2024 Felix Angelov 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without restriction, 7 | including without limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of the Software, 9 | and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 | USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /bricks/hello/README.md: -------------------------------------------------------------------------------- 1 | # hello 2 | 3 | A hello world brick created with the Mason CLI. 4 | 5 | _Generated by [mason][1] 🧱_ 6 | 7 | [1]: https://github.com/felangel/mason 8 | -------------------------------------------------------------------------------- /bricks/hello/__brick__/HELLO.md: -------------------------------------------------------------------------------- 1 | Hello {{name}}! 👋 -------------------------------------------------------------------------------- /bricks/hello/brick.yaml: -------------------------------------------------------------------------------- 1 | name: hello 2 | description: An example brick. 3 | repository: https://github.com/felangel/mason/tree/master/bricks/hello 4 | version: 0.1.0+2 5 | 6 | environment: 7 | mason: ^0.1.1 8 | 9 | vars: 10 | name: 11 | type: string 12 | description: Your name 13 | default: Dash 14 | prompt: What is your name? 15 | -------------------------------------------------------------------------------- /bricks/hello_world/__brick__/HELLO.md: -------------------------------------------------------------------------------- 1 | {{> common_header.md }} 2 | 3 | Hello {{name}}! 4 | 5 | {{> common_footer.md }} -------------------------------------------------------------------------------- /bricks/hello_world/__brick__/{{~ common_footer.md }}: -------------------------------------------------------------------------------- 1 | _made with 💖 by mason_ -------------------------------------------------------------------------------- /bricks/hello_world/__brick__/{{~ common_header.md }}: -------------------------------------------------------------------------------- 1 | # 🧱 {{name}} -------------------------------------------------------------------------------- /bricks/hello_world/brick.yaml: -------------------------------------------------------------------------------- 1 | name: hello_world 2 | description: A Simple Hello World Template 3 | version: 0.1.0+1 4 | vars: 5 | name: 6 | type: string 7 | description: Your name 8 | default: Dash 9 | prompt: What is your name? 10 | -------------------------------------------------------------------------------- /bricks/hooks/__brick__/hooks.md: -------------------------------------------------------------------------------- 1 | Hi {{name}}! -------------------------------------------------------------------------------- /bricks/hooks/brick.yaml: -------------------------------------------------------------------------------- 1 | name: hooks 2 | description: A Hooks Example Template 3 | version: 0.1.0+1 4 | vars: 5 | name: 6 | type: string 7 | description: Your name 8 | default: Dash 9 | prompt: What is your name? 10 | -------------------------------------------------------------------------------- /bricks/hooks/hooks/post_gen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io';import 'package:mason/mason.dart';void run(HookContext context){final file=File('.post_gen.txt');file.writeAsStringSync('post_gen: ${context.vars['name']}');} -------------------------------------------------------------------------------- /bricks/hooks/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io';import 'package:mason/mason.dart';void run(HookContext context){final file=File('.pre_gen.txt');file.writeAsStringSync('pre_gen: ${context.vars['name']}');} -------------------------------------------------------------------------------- /bricks/hooks/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: hooks_hooks 2 | 3 | environment: 4 | sdk: ^3.5.4 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /bricks/legacy/__brick__/GREETINGS.md: -------------------------------------------------------------------------------- 1 | Hi {{name}}! -------------------------------------------------------------------------------- /bricks/legacy/brick.yaml: -------------------------------------------------------------------------------- 1 | name: legacy 2 | description: A Legacy Greeting Template 3 | version: 0.1.0+1 4 | vars: 5 | - name -------------------------------------------------------------------------------- /bricks/photos/__brick__/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/bricks/photos/__brick__/image.png -------------------------------------------------------------------------------- /bricks/photos/brick.yaml: -------------------------------------------------------------------------------- 1 | name: photos 2 | description: A Photos Example Template 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /bricks/plugin/__brick__/README.md: -------------------------------------------------------------------------------- 1 | # Plugin 2 | -------------------------------------------------------------------------------- /bricks/plugin/__brick__/example/{{#android}}android.dart{{/android}}: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Android'); 3 | } -------------------------------------------------------------------------------- /bricks/plugin/__brick__/example/{{#ios}}ios.dart{{/ios}}: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Android'); 3 | } -------------------------------------------------------------------------------- /bricks/plugin/__brick__/tests/{{#android}}android_tests.dart{{/android}}: -------------------------------------------------------------------------------- 1 | void main() { 2 | test('Android Test', () {}); 3 | } -------------------------------------------------------------------------------- /bricks/plugin/__brick__/tests/{{#ios}}ios_tests.dart{{/ios}}: -------------------------------------------------------------------------------- 1 | void main() { 2 | test('iOS Test', () {}); 3 | } -------------------------------------------------------------------------------- /bricks/plugin/__brick__/{{#android}}android{{/android}}/README.md: -------------------------------------------------------------------------------- 1 | # Android Plugin 2 | -------------------------------------------------------------------------------- /bricks/plugin/__brick__/{{#android}}build.gradle{{/android}}: -------------------------------------------------------------------------------- 1 | // Empty build.gradle -------------------------------------------------------------------------------- /bricks/plugin/__brick__/{{#ios}}Podfile{{/ios}}: -------------------------------------------------------------------------------- 1 | # Empty Podfile -------------------------------------------------------------------------------- /bricks/plugin/__brick__/{{#ios}}ios{{/ios}}/README.md: -------------------------------------------------------------------------------- 1 | # iOS Plugin 2 | -------------------------------------------------------------------------------- /bricks/plugin/brick.yaml: -------------------------------------------------------------------------------- 1 | name: plugin 2 | description: An example plugin template 3 | version: 0.1.0+1 4 | vars: 5 | android: 6 | type: boolean 7 | description: Whether to generate an Android project. 8 | default: false 9 | prompt: Do you want to generate an Android project? 10 | ios: 11 | type: boolean 12 | description: Whether to generate an iOS project. 13 | default: false 14 | prompt: Do you want to generate an iOS project? 15 | -------------------------------------------------------------------------------- /bricks/random_color/__brick__/color.md: -------------------------------------------------------------------------------- 1 | Hi {{name}}! 2 | Your favorite color is {{favorite_color}}! -------------------------------------------------------------------------------- /bricks/random_color/brick.yaml: -------------------------------------------------------------------------------- 1 | name: random_color 2 | description: A Random Color Generator 3 | version: 0.1.0+1 4 | vars: 5 | name: 6 | type: string 7 | description: Your name 8 | default: Dash 9 | prompt: What is your name? 10 | -------------------------------------------------------------------------------- /bricks/random_color/hooks/post_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | 3 | void run(HookContext context) { 4 | context.logger.alert('Thanks for using random_color \u{1F3A8}!'); 5 | } 6 | -------------------------------------------------------------------------------- /bricks/random_color/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:mason/mason.dart'; 4 | 5 | const colors = [ 6 | 'Red', 7 | 'Green', 8 | 'Blue', 9 | 'Yellow', 10 | 'Cyan', 11 | 'Magenta', 12 | 'Pink', 13 | 'White', 14 | 'Black', 15 | ]; 16 | 17 | Future run(HookContext context) async { 18 | final progress = context.logger.progress('Generating a random color'); 19 | await Future.delayed(Duration(seconds: 1)); 20 | progress.complete('Generated'); 21 | final randomSeed = Random().nextInt(colors.length); 22 | context.vars['favorite_color'] = colors[randomSeed]; 23 | } 24 | -------------------------------------------------------------------------------- /bricks/random_color/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: random_color_hooks 2 | 3 | environment: 4 | sdk: ^3.5.4 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /bricks/simple/__brick__/HELLO.md: -------------------------------------------------------------------------------- 1 | Hello World! -------------------------------------------------------------------------------- /bricks/simple/brick.yaml: -------------------------------------------------------------------------------- 1 | name: simple 2 | description: A Simple Static Template 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /bricks/todos/__brick__/todos.md: -------------------------------------------------------------------------------- 1 | # TODOS 2 | 3 | {{#todos}} 4 | - {{#done}} [X] {{/done}}{{^done}} [ ] {{/done}} {{todo}} 5 | {{/todos}} 6 | -------------------------------------------------------------------------------- /bricks/todos/__brick__/todos/{{#todos}}todo_{{#upperCase}}{{{todo}}}{{/upperCase}}_todo.md{{/todos}}: -------------------------------------------------------------------------------- 1 | # TODO {{todos.todo}} 2 | 3 | {{#todos.done}}DONE!{{/todos.done}}{{^todos.done}}TODO{{/todos.done}} -------------------------------------------------------------------------------- /bricks/todos/__brick__/todos/{{#todos}}{{{todo}}}{{/todos}}/developers/{{#developers}}{{{name}}}{{/developers}}/info.md: -------------------------------------------------------------------------------- 1 | # {{developers.name}} 2 | 3 | ## TODO: {{todos.todo}} 4 | 5 | {{#todos.done}}**DONE**{{/todos.done}}{{^todos.done}}**TODO**{{/todos.done}} 6 | -------------------------------------------------------------------------------- /bricks/todos/brick.yaml: -------------------------------------------------------------------------------- 1 | name: todos 2 | description: A Todos Template 3 | version: 0.1.0+1 4 | vars: 5 | todos: 6 | type: string 7 | description: 'JSON Array of todos ([{"todo":"Walk Dog","done":false}])' 8 | default: '[{"todo":"Walk Dog","done":false}]' 9 | prompt: What is the list of todos? 10 | developers: 11 | type: string 12 | description: "JSON Array of developers ([{'name': 'Dash'}])" 13 | default: '[{"name": "Dash"}]' 14 | prompt: What is the list of developers? 15 | -------------------------------------------------------------------------------- /bricks/widget/__brick__/{{name.snakeCase()}}.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class {{name.pascalCase()}} extends StatelessWidget { 4 | const {{name.pascalCase()}}({super.key}); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return const SizedBox(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /bricks/widget/brick.yaml: -------------------------------------------------------------------------------- 1 | name: widget 2 | description: Create a Simple Flutter Widget 3 | version: 0.1.0+1 4 | vars: 5 | name: 6 | type: string 7 | description: The widget name 8 | default: MyWidget 9 | prompt: Please enter the widget name. 10 | -------------------------------------------------------------------------------- /cspell.config.yaml: -------------------------------------------------------------------------------- 1 | $schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json 2 | version: "0.2" 3 | ignorePaths: 4 | - "*_bundle.dart" 5 | words: 6 | - APPDATA 7 | - LOCALAPPDATA 8 | - mocktail 9 | - buildroot 10 | - endtemplate 11 | - writeln 12 | - recase 13 | - ints 14 | - combinators 15 | - tearoffs 16 | - pubspec 17 | - unawaited 18 | - interps 19 | - livestream 20 | - angelov 21 | - podfile 22 | - PANA 23 | - recompile 24 | - dartaotruntime 25 | - unbundle 26 | - xlink 27 | - struct 28 | - brickhub 29 | - felangel 30 | - Verdana 31 | - vscodeignore 32 | - nosources 33 | - recompiles 34 | - unbundling 35 | - sublist 36 | - Flutterly 37 | - antiprioritize # This might be an api mistake? 38 | - Yyna 39 | - dylib 40 | - libc 41 | - calloc 42 | - nullptr 43 | - xmit 44 | - keypress -------------------------------------------------------------------------------- /extensions/vscode/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": ["@stylistic", "@typescript-eslint"], 9 | "rules": { 10 | "@typescript-eslint/naming-convention": "warn", 11 | "@stylistic/semi": "warn", 12 | "curly": "warn", 13 | "eqeqeq": "warn", 14 | "no-throw-literal": "warn", 15 | "semi": "off" 16 | }, 17 | "ignorePatterns": ["out", "dist", "**/*.d.ts"] 18 | } 19 | -------------------------------------------------------------------------------- /extensions/vscode/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | out/ 3 | dist/ 4 | *.vsix -------------------------------------------------------------------------------- /extensions/vscode/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": ["dbaeumer.vscode-eslint", "amodio.tsl-problem-matcher"] 5 | } 6 | -------------------------------------------------------------------------------- /extensions/vscode/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": ["--extensionDevelopmentPath=${workspaceFolder}"], 13 | "outFiles": ["${workspaceFolder}/dist/**/*.js"], 14 | "preLaunchTask": "${defaultBuildTask}" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /extensions/vscode/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false, // set this to true to hide the "out" folder with the compiled JS files 5 | "dist": false // set this to true to hide the "dist" folder with the compiled JS files 6 | }, 7 | "search.exclude": { 8 | "out": true, // set this to false to include "out" folder in search results 9 | "dist": true // set this to false to include "dist" folder in search results 10 | }, 11 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 12 | "typescript.tsc.autoDetect": "off" 13 | } 14 | -------------------------------------------------------------------------------- /extensions/vscode/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": ["$ts-webpack-watch", "$tslint-webpack-watch"], 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never", 13 | "group": "watchers" 14 | }, 15 | "group": { 16 | "kind": "build", 17 | "isDefault": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /extensions/vscode/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/** 4 | node_modules/** 5 | src/** 6 | .gitignore 7 | .yarnrc 8 | webpack.config.js 9 | vsc-extension-quickstart.md 10 | **/tsconfig.json 11 | **/.eslintrc.json 12 | **/*.map 13 | **/*.ts 14 | -------------------------------------------------------------------------------- /extensions/vscode/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.1.12 2 | 3 | - refactor: various eslint fixes 4 | - deps: various dependency updates 5 | 6 | # 0.1.11 7 | 8 | - feat: support `list` variable type in `brick.yaml` 9 | - deps: various dependency updates 10 | 11 | # 0.1.10 12 | 13 | - feat: support mason new brick 14 | - deps: dependency updates 15 | 16 | # 0.1.9 17 | 18 | - feat: add support for `publish_to` field in `brick.yaml` 19 | - deps: various dependency updates 20 | 21 | # 0.1.8 22 | 23 | - fix: support spaces in mason make `--output-dir` 24 | 25 | # 0.1.7 26 | 27 | - fix: `mason.yaml` git url schema validation 28 | - support other formats such as `ssh` 29 | 30 | # 0.1.6 31 | 32 | - feat: YAML schema validation for `mason.yaml` 33 | - feat: YAML schema validation for `brick.yaml` 34 | 35 | # 0.1.5 36 | 37 | - fix: enum defaults to first value when no default specified 38 | 39 | # 0.1.4 40 | 41 | - fix: make command supports spaces in string variables 42 | 43 | # 0.1.3 44 | 45 | - fix: activate make commands when extension is initialized 46 | 47 | # 0.1.2 48 | 49 | - feat: add commands 50 | - Mason: Make Local Brick 51 | - Mason: Make Global Brick 52 | 53 | # 0.1.1 54 | 55 | - feat: add commands 56 | - Mason: Init 57 | - Mason: Add Local Brick 58 | - Mason: Add Global Brick 59 | - Mason: Remove Local Brick 60 | - Mason: Remove Global Brick 61 | 62 | # 0.1.0 63 | 64 | - feat: initial release 65 | - detect missing mason installation 66 | - automatically run `mason get` when `mason.yaml` is saved. 67 | -------------------------------------------------------------------------------- /extensions/vscode/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2024 Felix Angelov 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without restriction, 7 | including without limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of the Software, 9 | and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 | USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /extensions/vscode/README.md: -------------------------------------------------------------------------------- 1 | [Mason][mason_link] support for VSCode. 2 | 3 | ## Features 4 | 5 | - Initialize mason in the current workspace 6 | - Detect missing mason installation 7 | - Automatically gets bricks when `mason.yaml` is saved 8 | - Create new bricks 9 | - Add bricks to the local workspace 10 | - Add bricks globally 11 | - Remove bricks from the local workspace 12 | - Remove bricks globally 13 | - Mason make w/local bricks 14 | - Mason make w/global bricks 15 | - YAML schema validation for `mason.yaml` and `brick.yaml` files 16 | 17 | [mason_link]: https://github.com/felangel/mason 18 | -------------------------------------------------------------------------------- /extensions/vscode/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/extensions/vscode/assets/logo.png -------------------------------------------------------------------------------- /extensions/vscode/schema/mason.yaml.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "additionalProperties": false, 4 | "title": "mason.yaml", 5 | "description": "The mason.yaml schema for the mason ecosystem", 6 | "type": "object", 7 | "properties": { 8 | "bricks": { 9 | "type": ["object", "null"], 10 | "description": "A list of the registered bricks for the current workspace.", 11 | "patternProperties": { 12 | "^.*$": { 13 | "anyOf": [ 14 | { "$ref": "#/$defs/brickVersion" }, 15 | { "$ref": "#/$defs/brickPath" }, 16 | { "$ref": "#/$defs/brickGit" } 17 | ] 18 | }, 19 | "additionalProperties": false 20 | } 21 | } 22 | }, 23 | "required": ["bricks"], 24 | "$defs": { 25 | "brickVersion": { 26 | "type": "string", 27 | "description": "The version constraint for the associated brick (^1.0.0)." 28 | }, 29 | "brickPath": { 30 | "type": "object", 31 | "description": "The path location for the associated brick.", 32 | "properties": { 33 | "path": { 34 | "type": "string", 35 | "description": "The local path to the associated brick (./path/to/brick)." 36 | } 37 | }, 38 | "required": ["path"], 39 | "additionalProperties": false 40 | }, 41 | "brickGit": { 42 | "type": "object", 43 | "description": "A git reference.", 44 | "properties": { 45 | "git": { 46 | "type": "object", 47 | "description": "The git location for the associated brick.", 48 | "properties": { 49 | "url": { 50 | "type": "string", 51 | "description": "The git url for the associated brick (https://github.com/felangel/mason)." 52 | }, 53 | "path": { 54 | "type": "string", 55 | "description": "Path relative to the root of the repository (bricks/widget)." 56 | }, 57 | "ref": { 58 | "type": "string", 59 | "description": "Anything that git can use to identify a commit. Can be a branch name, tag, or commit hash." 60 | } 61 | }, 62 | "additionalProperties": false, 63 | "required": ["url"] 64 | }, 65 | "additionalProperties": false, 66 | "required": ["git"] 67 | }, 68 | "additionalProperties": false 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /extensions/vscode/src/commands/add-brick.ts: -------------------------------------------------------------------------------- 1 | import { isNil } from "lodash"; 2 | import * as vscode from "vscode"; 3 | import * as path from "path"; 4 | import { masonAdd } from "../mason"; 5 | 6 | export const addLocalBrick = async () => { 7 | const cwd = vscode.workspace.workspaceFolders?.[0].uri.fsPath; 8 | if (isNil(cwd)) { 9 | return; 10 | } 11 | 12 | try { 13 | const masonYamlPath = path.join(cwd, "mason.yaml"); 14 | await vscode.workspace.fs.stat(vscode.Uri.file(masonYamlPath)); 15 | } catch (_) { 16 | vscode.window.showErrorMessage( 17 | "No mason.yaml was found in the current workspace.", 18 | ); 19 | return; 20 | } 21 | 22 | const brick = await promptForBrickName(); 23 | if (isNil(brick)) { 24 | return; 25 | } 26 | 27 | await masonAdd({ cwd, brick }); 28 | }; 29 | 30 | export const addGlobalBrick = async () => { 31 | const cwd = vscode.workspace.workspaceFolders?.[0].uri.fsPath; 32 | if (isNil(cwd)) { 33 | return; 34 | } 35 | 36 | const brick = await promptForBrickName(); 37 | if (isNil(brick)) { 38 | return; 39 | } 40 | 41 | await masonAdd({ cwd, brick, global: true }); 42 | }; 43 | 44 | const promptForBrickName = () => { 45 | return vscode.window.showInputBox({ 46 | placeHolder: "hello", 47 | prompt: "Enter the brick name.", 48 | }); 49 | }; 50 | -------------------------------------------------------------------------------- /extensions/vscode/src/commands/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./add-brick"; 2 | export * from "./init"; 3 | export * from "./make-brick"; 4 | export * from "./new-brick"; 5 | export * from "./remove-brick"; 6 | -------------------------------------------------------------------------------- /extensions/vscode/src/commands/init.ts: -------------------------------------------------------------------------------- 1 | import { isNil } from "lodash"; 2 | import * as vscode from "vscode"; 3 | import * as path from "path"; 4 | import { masonInit } from "../mason"; 5 | 6 | export const init = async () => { 7 | const cwd = vscode.workspace.workspaceFolders?.[0].uri.fsPath; 8 | if (isNil(cwd)) { 9 | return; 10 | } 11 | 12 | try { 13 | const masonYamlPath = path.join(cwd, "mason.yaml"); 14 | await vscode.workspace.fs.stat(vscode.Uri.file(masonYamlPath)); 15 | vscode.window.showErrorMessage( 16 | "A mason.yaml already exists in the current workspace.", 17 | ); 18 | return; 19 | } catch (_) {} 20 | 21 | await masonInit({ cwd }); 22 | }; 23 | -------------------------------------------------------------------------------- /extensions/vscode/src/commands/new-brick.ts: -------------------------------------------------------------------------------- 1 | import { lstatSync } from "fs"; 2 | import { get, isNil } from "lodash"; 3 | import * as vscode from "vscode"; 4 | import { masonNew } from "../mason"; 5 | import { promptForTargetDirectory } from "../utils"; 6 | 7 | export const newBrick = async (uri: vscode.Uri) => { 8 | const cwd = vscode.workspace.workspaceFolders?.[0].uri.fsPath; 9 | if (isNil(cwd)) { 10 | return; 11 | } 12 | 13 | let targetDirectory; 14 | 15 | if (isNil(get(uri, "fsPath")) || !lstatSync(uri.fsPath).isDirectory()) { 16 | targetDirectory = await promptForTargetDirectory(); 17 | if (isNil(targetDirectory)) { 18 | vscode.window.showErrorMessage("Please select a valid directory"); 19 | return; 20 | } 21 | } else { 22 | targetDirectory = uri.fsPath; 23 | } 24 | 25 | const brick = await promptForBrickName(); 26 | if (isNil(brick)) { 27 | return; 28 | } 29 | 30 | const useHooks = await promptForHooks(); 31 | const hooks = useHooks === "yes"; 32 | 33 | await masonNew({ targetDirectory, brick, hooks }); 34 | }; 35 | 36 | const promptForBrickName = () => { 37 | return vscode.window.showInputBox({ 38 | placeHolder: "my_brick", 39 | prompt: "Enter the brick name.", 40 | }); 41 | }; 42 | 43 | const promptForHooks = () => { 44 | return vscode.window.showQuickPick(["no", "yes"], { 45 | canPickMany: false, 46 | placeHolder: "Do you want to generate hooks as part of the brick?", 47 | }); 48 | }; 49 | -------------------------------------------------------------------------------- /extensions/vscode/src/commands/remove-brick.ts: -------------------------------------------------------------------------------- 1 | import { isNil } from "lodash"; 2 | import * as vscode from "vscode"; 3 | import * as path from "path"; 4 | import { masonRemove } from "../mason"; 5 | 6 | export const removeLocalBrick = async () => { 7 | const cwd = vscode.workspace.workspaceFolders?.[0].uri.fsPath; 8 | if (isNil(cwd)) { 9 | return; 10 | } 11 | 12 | try { 13 | const masonYamlPath = path.join(cwd, "mason.yaml"); 14 | await vscode.workspace.fs.stat(vscode.Uri.file(masonYamlPath)); 15 | } catch (_) { 16 | vscode.window.showErrorMessage( 17 | "No mason.yaml was found in the current workspace.", 18 | ); 19 | return; 20 | } 21 | 22 | const brick = await promptForBrickName(); 23 | if (isNil(brick)) { 24 | return; 25 | } 26 | 27 | await masonRemove({ cwd, brick }); 28 | }; 29 | 30 | export const removeGlobalBrick = async () => { 31 | const cwd = vscode.workspace.workspaceFolders?.[0].uri.fsPath; 32 | if (isNil(cwd)) { 33 | return; 34 | } 35 | 36 | const brick = await promptForBrickName(); 37 | if (isNil(brick)) { 38 | return; 39 | } 40 | 41 | await masonRemove({ cwd, brick, global: true }); 42 | }; 43 | 44 | const promptForBrickName = () => { 45 | return vscode.window.showInputBox({ 46 | placeHolder: "hello", 47 | prompt: "Enter the brick name.", 48 | }); 49 | }; 50 | -------------------------------------------------------------------------------- /extensions/vscode/src/events/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./on-file-saved"; 2 | -------------------------------------------------------------------------------- /extensions/vscode/src/events/on-file-saved.ts: -------------------------------------------------------------------------------- 1 | import * as path from "path"; 2 | import * as vscode from "vscode"; 3 | import { masonGet } from "../mason"; 4 | 5 | export const onFileSaved = async (document: vscode.TextDocument) => { 6 | if (path.basename(document.uri.fsPath) !== "mason.yaml") { 7 | return; 8 | } 9 | await masonGet({ cwd: path.join(document.uri.fsPath, "..") }); 10 | }; 11 | -------------------------------------------------------------------------------- /extensions/vscode/src/extension.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { 3 | addLocalBrick, 4 | addGlobalBrick, 5 | init, 6 | makeLocalBrick, 7 | makeGlobalBrick, 8 | newBrick, 9 | removeLocalBrick, 10 | removeGlobalBrick, 11 | } from "./commands"; 12 | import { onFileSaved } from "./events"; 13 | 14 | export async function activate(context: vscode.ExtensionContext) { 15 | context.subscriptions.push( 16 | vscode.workspace.onDidSaveTextDocument(onFileSaved), 17 | vscode.commands.registerCommand("mason.init", init), 18 | vscode.commands.registerCommand("mason.new-brick", newBrick), 19 | vscode.commands.registerCommand("mason.add-local-brick", addLocalBrick), 20 | vscode.commands.registerCommand("mason.add-global-brick", addGlobalBrick), 21 | vscode.commands.registerCommand("mason.make-local-brick", makeLocalBrick), 22 | vscode.commands.registerCommand("mason.make-global-brick", makeGlobalBrick), 23 | vscode.commands.registerCommand( 24 | "mason.remove-local-brick", 25 | removeLocalBrick, 26 | ), 27 | vscode.commands.registerCommand( 28 | "mason.remove-global-brick", 29 | removeGlobalBrick, 30 | ), 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/get-brick-yaml.ts: -------------------------------------------------------------------------------- 1 | import * as path from "path"; 2 | import * as YAML from "yaml"; 3 | import { existsSync, readFileSync } from "fs"; 4 | 5 | interface BrickYaml { 6 | name: string; 7 | vars: Record; 8 | } 9 | 10 | export const getBrickYaml = async ({ 11 | brickPath, 12 | }: { 13 | brickPath: string; 14 | }): Promise => { 15 | const brickYamlPath = path.join(brickPath, "brick.yaml"); 16 | if (!existsSync(brickYamlPath)) { 17 | return undefined; 18 | } 19 | return YAML.parse(readFileSync(brickYamlPath, { encoding: "utf-8" })); 20 | }; 21 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get-brick-yaml"; 2 | export * from "./is-mason-installed"; 3 | export * from "./mason-add"; 4 | export * from "./mason-exec"; 5 | export * from "./mason-get"; 6 | export * from "./mason-init"; 7 | export * from "./mason-make"; 8 | export * from "./mason-new"; 9 | export * from "./mason-remove"; 10 | 11 | export const statusBarTimeout = 3000; 12 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/is-mason-installed.ts: -------------------------------------------------------------------------------- 1 | import { exec } from "../utils"; 2 | 3 | export const isMasonInstalled = async (): Promise => { 4 | try { 5 | await exec("mason"); 6 | return true; 7 | } catch (_) { 8 | return false; 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/mason-add.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { masonExec, statusBarTimeout } from "."; 3 | 4 | export const masonAdd = async ({ 5 | cwd, 6 | brick, 7 | global = false, 8 | }: { 9 | cwd: string; 10 | brick: string; 11 | global?: boolean; 12 | }): Promise => { 13 | return vscode.window.withProgress( 14 | { 15 | location: vscode.ProgressLocation.Window, 16 | title: `mason add${global ? " -g " : " "}${brick}`, 17 | }, 18 | async (_) => { 19 | try { 20 | await masonExec(`add${global ? " -g " : " "}${brick}`, { 21 | cwd: cwd, 22 | }); 23 | vscode.window.setStatusBarMessage( 24 | `✓ mason add${global ? " -g " : " "}${brick}`, 25 | statusBarTimeout, 26 | ); 27 | } catch (err) { 28 | vscode.window.showErrorMessage(`${err}`); 29 | } 30 | }, 31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/mason-exec.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { isMasonInstalled } from "."; 3 | import { exec, ExecOptions } from "../utils"; 4 | 5 | let _terminal: vscode.Terminal | undefined; 6 | 7 | export const masonExec = async (cmd: string, options?: ExecOptions) => { 8 | const masonInstalled = await isMasonInstalled(); 9 | if (!masonInstalled) { 10 | showMissingInstallationWarning(); 11 | return; 12 | } 13 | 14 | return exec(`mason ${cmd}`, { 15 | cwd: options?.cwd, 16 | }); 17 | }; 18 | 19 | export const masonSpawn = async (cmd: string) => { 20 | const masonInstalled = await isMasonInstalled(); 21 | if (!masonInstalled) { 22 | showMissingInstallationWarning(); 23 | return; 24 | } 25 | 26 | _terminal?.dispose(); 27 | _terminal = vscode.window.createTerminal("mason"); 28 | 29 | _terminal.show(); 30 | _terminal.sendText(`mason ${cmd}`); 31 | }; 32 | 33 | const showMissingInstallationWarning = () => { 34 | vscode.window 35 | .showWarningMessage( 36 | "No mason installation was found.", 37 | "Open installation instructions", 38 | ) 39 | .then((_) => { 40 | if (_) { 41 | vscode.env.openExternal( 42 | vscode.Uri.parse( 43 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#installation", 44 | ), 45 | ); 46 | } 47 | }); 48 | }; 49 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/mason-get.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { masonExec, statusBarTimeout } from "."; 3 | 4 | export const masonGet = async ({ cwd }: { cwd: string }): Promise => { 5 | return vscode.window.withProgress( 6 | { 7 | location: vscode.ProgressLocation.Window, 8 | title: "mason get", 9 | }, 10 | async (_) => { 11 | try { 12 | await masonExec("get", { 13 | cwd: cwd, 14 | }); 15 | vscode.window.setStatusBarMessage("✓ mason get", statusBarTimeout); 16 | } catch (err) { 17 | vscode.window.showErrorMessage(`${err}`); 18 | } 19 | }, 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/mason-init.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { masonExec, statusBarTimeout } from "."; 3 | 4 | export const masonInit = async ({ cwd }: { cwd: string }): Promise => { 5 | return vscode.window.withProgress( 6 | { 7 | location: vscode.ProgressLocation.Window, 8 | title: "mason init", 9 | }, 10 | async (_) => { 11 | try { 12 | await masonExec("init", { 13 | cwd: cwd, 14 | }); 15 | vscode.window.setStatusBarMessage("✓ mason init", statusBarTimeout); 16 | } catch (err) { 17 | vscode.window.showErrorMessage(`${err}`); 18 | } 19 | }, 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/mason-make.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { masonSpawn, statusBarTimeout } from "."; 3 | 4 | export const masonMake = async ({ 5 | targetDirectory, 6 | name, 7 | args, 8 | }: { 9 | targetDirectory: string; 10 | name: string; 11 | args: string; 12 | }): Promise => { 13 | return vscode.window.withProgress( 14 | { 15 | location: vscode.ProgressLocation.Window, 16 | title: `mason make ${name}`, 17 | }, 18 | async (_) => { 19 | try { 20 | await masonSpawn( 21 | `make ${name} ${args} --output-dir="${targetDirectory}" --on-conflict=skip`, 22 | ); 23 | vscode.window.setStatusBarMessage( 24 | `✓ mason make ${name}`, 25 | statusBarTimeout, 26 | ); 27 | } catch (err) { 28 | vscode.window.showErrorMessage(`${err}`); 29 | } 30 | }, 31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/mason-new.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { masonExec, statusBarTimeout } from "."; 3 | 4 | export const masonNew = async ({ 5 | targetDirectory, 6 | brick, 7 | hooks = false, 8 | }: { 9 | targetDirectory: string; 10 | brick: string; 11 | hooks?: boolean; 12 | }): Promise => { 13 | return vscode.window.withProgress( 14 | { 15 | location: vscode.ProgressLocation.Window, 16 | title: `mason new ${brick} ${hooks ? "--hooks" : ""}`, 17 | }, 18 | async (_) => { 19 | try { 20 | await masonExec(`new ${brick} ${hooks ? "--hooks" : ""}`, { 21 | cwd: targetDirectory, 22 | }); 23 | vscode.window.setStatusBarMessage( 24 | `✓ mason new ${brick} ${hooks ? "--hooks" : ""}`, 25 | statusBarTimeout, 26 | ); 27 | } catch (err) { 28 | vscode.window.showErrorMessage(`${err}`); 29 | } 30 | }, 31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /extensions/vscode/src/mason/mason-remove.ts: -------------------------------------------------------------------------------- 1 | import { isNil } from "lodash"; 2 | import * as vscode from "vscode"; 3 | import { masonExec, statusBarTimeout } from "."; 4 | 5 | export const masonRemove = async ({ 6 | cwd, 7 | brick, 8 | global = false, 9 | }: { 10 | cwd: string; 11 | brick: string; 12 | global?: boolean; 13 | }): Promise => { 14 | return vscode.window.withProgress( 15 | { 16 | location: vscode.ProgressLocation.Window, 17 | title: `mason remove${global ? " -g " : " "}${brick}`, 18 | }, 19 | async (__) => { 20 | const document = vscode.window.activeTextEditor?.document; 21 | if (isNil(document)) { 22 | return; 23 | } 24 | 25 | try { 26 | await masonExec(`remove${global ? " -g " : " "}${brick}`, { 27 | cwd: cwd, 28 | }); 29 | vscode.window.setStatusBarMessage( 30 | `✓ mason remove${global ? " -g " : " "}${brick}`, 31 | statusBarTimeout, 32 | ); 33 | } catch (err) { 34 | vscode.window.showErrorMessage(`${err}`); 35 | } 36 | }, 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /extensions/vscode/src/utils/exec.ts: -------------------------------------------------------------------------------- 1 | import * as cp from "child_process"; 2 | 3 | export interface ExecOptions { 4 | cwd?: string | undefined; 5 | } 6 | 7 | export const exec = (cmd: string, options?: ExecOptions) => 8 | new Promise((resolve, reject) => { 9 | cp.exec(cmd, { cwd: options?.cwd }, (err, output) => { 10 | if (err) { 11 | return reject(err); 12 | } 13 | return resolve(output); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /extensions/vscode/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./exec"; 2 | export * from "./prompt-for-target-directory"; 3 | -------------------------------------------------------------------------------- /extensions/vscode/src/utils/prompt-for-target-directory.ts: -------------------------------------------------------------------------------- 1 | import { isEmpty, isNil } from "lodash"; 2 | import * as vscode from "vscode"; 3 | 4 | export async function promptForTargetDirectory(): Promise { 5 | const options: vscode.OpenDialogOptions = { 6 | canSelectMany: false, 7 | openLabel: "Select a folder", 8 | canSelectFolders: true, 9 | }; 10 | 11 | return vscode.window.showOpenDialog(options).then((uri) => { 12 | if (isNil(uri) || isEmpty(uri)) { 13 | return undefined; 14 | } 15 | return uri[0].fsPath; 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /extensions/vscode/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "lib": ["ES2020"], 6 | "sourceMap": true, 7 | "rootDir": "src", 8 | "strict": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "noUnusedParameters": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /extensions/vscode/webpack.config.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | "use strict"; 4 | 5 | const path = require("path"); 6 | 7 | //@ts-check 8 | /** @typedef {import('webpack').Configuration} WebpackConfig **/ 9 | 10 | /** @type WebpackConfig */ 11 | const extensionConfig = { 12 | target: "node", // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ 13 | mode: "none", // this leaves the source code as close as possible to the original (when packaging we set this to 'production') 14 | 15 | entry: "./src/extension.ts", // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ 16 | output: { 17 | // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ 18 | path: path.resolve(__dirname, "dist"), 19 | filename: "extension.js", 20 | libraryTarget: "commonjs2", 21 | }, 22 | externals: { 23 | vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ 24 | // modules added here also need to be added in the .vscodeignore file 25 | }, 26 | resolve: { 27 | // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader 28 | extensions: [".ts", ".js"], 29 | }, 30 | module: { 31 | rules: [ 32 | { 33 | test: /\.ts$/, 34 | exclude: /node_modules/, 35 | use: [ 36 | { 37 | loader: "ts-loader", 38 | }, 39 | ], 40 | }, 41 | ], 42 | }, 43 | devtool: "nosources-source-map", 44 | infrastructureLogging: { 45 | level: "log", // enables logging required for problem matchers 46 | }, 47 | }; 48 | module.exports = [extensionConfig]; 49 | -------------------------------------------------------------------------------- /packages/mason/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | # Remove the following pattern if you wish to check in your lock file 5 | pubspec.lock 6 | 7 | # Conventional directory for build outputs 8 | build/ 9 | 10 | # Directory created by dartdoc 11 | doc/api/ 12 | 13 | # Temporary Files 14 | .tmp/ 15 | 16 | # Local Mason Files 17 | .mason/ 18 | 19 | # Test Related Files 20 | coverage/ 21 | test/fixtures/.*/ 22 | .test_coverage.dart 23 | 24 | # Exceptions to the above rules 25 | !test/fixtures/*/.mason/ -------------------------------------------------------------------------------- /packages/mason/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2024 Felix Angelov 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without restriction, 7 | including without limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of the Software, 9 | and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 | USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/mason/README.md: -------------------------------------------------------------------------------- 1 |

2 | mason logo 3 |

4 | 5 |

6 | Pub 7 | mason 8 | coverage 9 | License: MIT 10 |

11 | 12 | --- 13 | 14 | A template generator which helps teams generate files quickly and consistently. 15 | 16 | `package:mason` contains the core generator that powers [package:mason_cli](https://pub.dev/packages/mason_cli) and can be used to build custom code generation tools. 17 | 18 | ```dart 19 | import 'dart:io'; 20 | 21 | import 'package:mason/mason.dart'; 22 | 23 | Future main() async { 24 | final brick = Brick.git( 25 | const GitPath( 26 | 'https://github.com/felangel/mason', 27 | path: 'bricks/greeting', 28 | ), 29 | ); 30 | final generator = await MasonGenerator.fromBrick(brick); 31 | final target = DirectoryGeneratorTarget(Directory.current); 32 | await generator.generate(target, vars: {'name': 'Dash'}); 33 | } 34 | ``` 35 | -------------------------------------------------------------------------------- /packages/mason/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: ../../analysis_options.yaml 2 | analyzer: 3 | exclude: 4 | - "test/.test_coverage.dart" 5 | - "test/fixtures/**" 6 | - "**/*.g.dart" 7 | - "lib/src/version.dart" 8 | linter: 9 | rules: 10 | no_leading_underscores_for_local_identifiers: false 11 | -------------------------------------------------------------------------------- /packages/mason/build.yaml: -------------------------------------------------------------------------------- 1 | # See https://github.com/dart-lang/build/tree/master/build_web_compilers#configuration 2 | targets: 3 | $default: 4 | sources: 5 | exclude: 6 | - test/** 7 | builders: 8 | json_serializable: 9 | options: 10 | any_map: true 11 | disallow_unrecognized_keys: true 12 | field_rename: kebab 13 | include_if_null: false 14 | checked: true 15 | explicit_to_json: true 16 | create_to_json: true 17 | -------------------------------------------------------------------------------- /packages/mason/coverage_badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | coverage 16 | coverage 17 | 100% 18 | 100% 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/mason/example/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:mason/mason.dart'; 4 | 5 | Future main() async { 6 | final brick = Brick.git( 7 | const GitPath( 8 | 'https://github.com/felangel/mason.git', 9 | path: 'bricks/greeting', 10 | ), 11 | ); 12 | final generator = await MasonGenerator.fromBrick(brick); 13 | final target = DirectoryGeneratorTarget(Directory.current); 14 | await generator.generate(target, vars: {'name': 'Dash'}); 15 | } 16 | -------------------------------------------------------------------------------- /packages/mason/lib/mason.dart: -------------------------------------------------------------------------------- 1 | /// A Dart template generator which helps teams 2 | /// generate files quickly and consistently. 3 | /// 4 | /// Get started at [https://github.com/felangel/mason](https://github.com/felangel/mason) 🧱 5 | library mason; 6 | 7 | export 'package:mason_logger/mason_logger.dart'; 8 | export 'package:pub_semver/pub_semver.dart' 9 | show Version, VersionConstraint, VersionRange; 10 | 11 | export 'src/brick.dart' show Brick; 12 | export 'src/brick_compatibility.dart' show isBrickCompatibleWithMason; 13 | export 'src/brick_yaml.dart' 14 | show 15 | BrickEnvironment, 16 | BrickVariableProperties, 17 | BrickVariableType, 18 | BrickYaml; 19 | export 'src/bricks_json.dart' show BricksJson, CachedBrick; 20 | export 'src/bundler.dart' show createBundle, unpackBundle; 21 | export 'src/exception.dart' show BrickNotFoundException, MasonException; 22 | export 'src/generator.dart' 23 | show 24 | DirectoryGeneratorTarget, 25 | FileConflictResolution, 26 | GeneratedFile, 27 | GeneratedFileStatus, 28 | GeneratorHooks, 29 | GeneratorTarget, 30 | HookContext, 31 | MasonGenerator, 32 | OverwriteRule, 33 | TemplateFile; 34 | export 'src/mason_bundle.dart' show MasonBundle, MasonBundledFile; 35 | export 'src/mason_lock_json.dart' show MasonLockJson; 36 | export 'src/mason_yaml.dart' show BrickLocation, GitPath, MasonYaml; 37 | export 'src/path.dart' show canonicalize; 38 | export 'src/render.dart' show RenderTemplate; 39 | export 'src/string_case_extensions.dart' show StringCaseExtensions; 40 | export 'src/version.dart' show packageVersion; 41 | export 'src/yaml_encode.dart' show Yaml; 42 | -------------------------------------------------------------------------------- /packages/mason/lib/src/brick.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | 3 | /// {@template brick} 4 | /// Metadata for a brick template including the name and location. 5 | /// {@endtemplate} 6 | class Brick { 7 | /// {@macro brick} 8 | const Brick({required this.location, this.name}); 9 | 10 | /// Brick from a local path. 11 | Brick.path(String path) : this(location: BrickLocation(path: path)); 12 | 13 | /// Brick from a git url. 14 | Brick.git(GitPath git) : this(location: BrickLocation(git: git)); 15 | 16 | /// Brick from a version constraint. 17 | Brick.version({required String name, required String version}) 18 | : this( 19 | name: name, 20 | location: BrickLocation(version: version), 21 | ); 22 | 23 | /// The name of the brick. 24 | final String? name; 25 | 26 | /// The location of the brick. 27 | final BrickLocation location; 28 | } 29 | -------------------------------------------------------------------------------- /packages/mason/lib/src/brick_compatibility.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | 3 | /// Returns whether the current [brickYaml] is compatible 4 | /// with the current version of mason. 5 | bool isBrickCompatibleWithMason(BrickYaml brickYaml) { 6 | final currentMasonVersion = Version.parse(packageVersion); 7 | final masonVersionConstraint = VersionConstraint.parse( 8 | brickYaml.environment.mason, 9 | ); 10 | 11 | return masonVersionConstraint.allows(currentMasonVersion); 12 | } 13 | -------------------------------------------------------------------------------- /packages/mason/lib/src/exception.dart: -------------------------------------------------------------------------------- 1 | /// {@template mason_exception} 2 | /// An exception thrown by an internal mason command. 3 | /// {@endtemplate} 4 | class MasonException implements Exception { 5 | /// {@macro mason_exception} 6 | const MasonException(this.message); 7 | 8 | /// The error message which will be displayed to the user via stderr. 9 | final String message; 10 | 11 | @override 12 | String toString() => message; 13 | } 14 | 15 | /// {@template brick_not_found_exception} 16 | /// Thrown when a brick registered in the `mason.yaml` cannot be found locally. 17 | /// {@endtemplate} 18 | class BrickNotFoundException extends MasonException { 19 | /// {@macro brick_not_found_exception} 20 | const BrickNotFoundException(String path) 21 | : super('Could not find brick at $path'); 22 | } 23 | -------------------------------------------------------------------------------- /packages/mason/lib/src/git.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | /// Git Interface 4 | class Git { 5 | /// Execute a git command and returns a [ProcessResult]. 6 | static Future run( 7 | List args, { 8 | bool throwOnError = true, 9 | String? processWorkingDir, 10 | }) async { 11 | final result = await Process.run( 12 | 'git', 13 | args, 14 | workingDirectory: processWorkingDir, 15 | runInShell: true, 16 | ); 17 | 18 | if (throwOnError) { 19 | _throwIfProcessFailed(result, 'git', args); 20 | } 21 | return result; 22 | } 23 | } 24 | 25 | void _throwIfProcessFailed( 26 | ProcessResult pr, 27 | String process, 28 | List args, 29 | ) { 30 | if (pr.exitCode != 0) { 31 | final values = { 32 | 'Standard out': pr.stdout.toString().trim(), 33 | 'Standard error': pr.stderr.toString().trim(), 34 | }..removeWhere((k, v) => v.isEmpty); 35 | 36 | var message = 'Unknown error'; 37 | if (values.isNotEmpty) { 38 | message = values.entries.map((e) => '${e.key}\n${e.value}').join('\n'); 39 | } 40 | 41 | throw ProcessException(process, args, message, pr.exitCode); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/mason/lib/src/mason_lock_json.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:mason/mason.dart'; 3 | 4 | part 'mason_lock_json.g.dart'; 5 | 6 | /// {@template mason_lock_json} 7 | /// Mason lock file which contains locked brick locations. 8 | /// {@endtemplate} 9 | @JsonSerializable() 10 | class MasonLockJson { 11 | /// {@macro mason_lock_json} 12 | const MasonLockJson({Map? bricks}) 13 | : bricks = bricks ?? const {}; 14 | 15 | /// Converts [Map] to [MasonLockJson] 16 | factory MasonLockJson.fromJson(Map json) => 17 | _$MasonLockJsonFromJson(json); 18 | 19 | /// Converts [MasonLockJson] to [Map] 20 | Map toJson() => _$MasonLockJsonToJson(this); 21 | 22 | /// static constant for mason lock file name. 23 | /// `mason-lock.json` 24 | static const file = 'mason-lock.json'; 25 | 26 | /// static constant for an empty `mason-lock.yaml` file. 27 | static const empty = MasonLockJson(); 28 | 29 | /// [Map] of [BrickLocation] alias to [BrickLocation] instances. 30 | final Map bricks; 31 | } 32 | -------------------------------------------------------------------------------- /packages/mason/lib/src/mason_lock_json.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'mason_lock_json.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | MasonLockJson _$MasonLockJsonFromJson(Map json) => $checkedCreate( 10 | 'MasonLockJson', 11 | json, 12 | ($checkedConvert) { 13 | $checkKeys( 14 | json, 15 | allowedKeys: const ['bricks'], 16 | ); 17 | final val = MasonLockJson( 18 | bricks: $checkedConvert( 19 | 'bricks', 20 | (v) => (v as Map?)?.map( 21 | (k, e) => MapEntry(k as String, BrickLocation.fromJson(e)), 22 | )), 23 | ); 24 | return val; 25 | }, 26 | ); 27 | 28 | Map _$MasonLockJsonToJson(MasonLockJson instance) => 29 | { 30 | 'bricks': instance.bricks.map((k, e) => MapEntry(k, e.toJson())), 31 | }; 32 | -------------------------------------------------------------------------------- /packages/mason/lib/src/path.dart: -------------------------------------------------------------------------------- 1 | import 'package:path/path.dart' as p; 2 | 3 | /// Canonicalizes [path]. 4 | /// 5 | /// This function implements the behavior of `canonicalize` from 6 | /// `package:path`. 7 | /// However, it does not change the ASCII case of the path. 8 | /// See https://github.com/dart-lang/path/issues/102. 9 | String canonicalize(String path) { 10 | return p.normalize(p.absolute(path)).replaceAll(r'\', '/'); 11 | } 12 | 13 | /// Normalizes the [path]. 14 | String normalize(String path) => p.normalize(path).replaceAll(r'\', '/'); 15 | -------------------------------------------------------------------------------- /packages/mason/lib/src/string_case_extensions.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/src/recase.dart'; 2 | 3 | /// Built-in [String] casing extensions. 4 | extension StringCaseExtensions on String { 5 | /// camelCase 6 | String get camelCase => ReCase(this).camelCase; 7 | 8 | /// CONSTANT_CASE 9 | String get constantCase => ReCase(this).constantCase; 10 | 11 | /// dot.case 12 | String get dotCase => ReCase(this).dotCase; 13 | 14 | /// Header-Case 15 | String get headerCase => ReCase(this).headerCase; 16 | 17 | /// lower case 18 | String get lowerCase => toLowerCase(); 19 | 20 | /// {{ mustache case }} 21 | String get mustacheCase => '{{ $this }}'; 22 | 23 | /// PascalCase 24 | String get pascalCase => ReCase(this).pascalCase; 25 | 26 | /// Pascal.Dot.Case 27 | String get pascalDotCase => ReCase(this).pascalDotCase; 28 | 29 | /// param-case 30 | String get paramCase => ReCase(this).paramCase; 31 | 32 | /// path/case 33 | String get pathCase => ReCase(this).pathCase; 34 | 35 | /// Sentence case 36 | String get sentenceCase => ReCase(this).sentenceCase; 37 | 38 | /// snake_case 39 | String get snakeCase => ReCase(this).snakeCase; 40 | 41 | /// Title Case 42 | String get titleCase => ReCase(this).titleCase; 43 | 44 | /// UPPER CASE 45 | String get upperCase => toUpperCase(); 46 | } 47 | -------------------------------------------------------------------------------- /packages/mason/lib/src/version.dart: -------------------------------------------------------------------------------- 1 | // Generated code. Do not modify. 2 | const packageVersion = '0.1.1'; 3 | -------------------------------------------------------------------------------- /packages/mason/lib/src/yaml_encode.dart: -------------------------------------------------------------------------------- 1 | /// Yaml Utilities 2 | class Yaml { 3 | /// Encodes a [Map] as `yaml` similar to `json.encode`. 4 | static String encode(Map json, [int nestingLevel = 0]) { 5 | return json.entries 6 | .map((entry) => _formatEntry(entry, nestingLevel)) 7 | .join('\n'); 8 | } 9 | } 10 | 11 | String _formatEntry(MapEntry entry, int nesting) { 12 | return '''${_indentation(nesting)}${entry.key}:${_formatValue(entry.value, nesting)}'''; 13 | } 14 | 15 | String _formatValue(dynamic value, int nesting) { 16 | if (value is Map) { 17 | return '\n${Yaml.encode(value, nesting + 1)}'; 18 | } 19 | if (value is List) { 20 | return '\n${_formatList(value, nesting + 1)}'; 21 | } 22 | if (value is String) { 23 | if (_isMultilineString(value)) { 24 | return ''' |\n${value.split('\n').map((s) => '${_indentation(nesting + 1)}$s').join('\n')}'''; 25 | } 26 | if (_containsEscapeCharacters(value)) { 27 | return ' "${_withEscapes(value)}"'; 28 | } 29 | if (_containsSpecialCharacters(value)) { 30 | return ' "$value"'; 31 | } 32 | } 33 | if (value == null) { 34 | return ''; 35 | } 36 | return ' $value'; 37 | } 38 | 39 | String _formatList(List list, int nesting) { 40 | return list.map((dynamic value) { 41 | return '${_indentation(nesting)}-${_formatValue(value, nesting + 2)}'; 42 | }).join('\n'); 43 | } 44 | 45 | String _indentation(int nesting) => _spaces(nesting * 2); 46 | String _spaces(int n) => ''.padRight(n); 47 | 48 | bool _isMultilineString(String s) => s.contains('\n'); 49 | 50 | bool _containsSpecialCharacters(String s) => 51 | _specialCharacters.any((c) => s.contains(c)); 52 | 53 | final _specialCharacters = ':{}[],&*#?|-<>=!%@'.split(''); 54 | 55 | bool _containsEscapeCharacters(String s) => 56 | _escapeCharacters.any((c) => s.contains(c)); 57 | 58 | final _escapeCharacters = [ 59 | r'\', 60 | '\r', 61 | '\t', 62 | '\n', 63 | '"', 64 | "'", 65 | '™', 66 | '', 67 | ]; 68 | 69 | String _withEscapes(String s) => s 70 | .replaceAll(r'\', r'\\') 71 | .replaceAll('\r', r'\r') 72 | .replaceAll('\t', r'\t') 73 | .replaceAll('\n', r'\n') 74 | .replaceAll('"', r'\"') 75 | .replaceAll('™', '\x99') 76 | .replaceAll('', '\x9D'); 77 | -------------------------------------------------------------------------------- /packages/mason/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mason 2 | description: > 3 | A Dart template generator which helps teams generate files quickly and consistently. 4 | version: 0.1.1 5 | homepage: https://github.com/felangel/mason 6 | repository: https://github.com/felangel/mason 7 | issue_tracker: https://github.com/felangel/mason/issues 8 | documentation: https://docs.brickhub.dev 9 | topics: [mason, template, generator] 10 | funding: [https://github.com/sponsors/felangel] 11 | 12 | platforms: 13 | android: 14 | ios: 15 | linux: 16 | macos: 17 | web: 18 | windows: 19 | 20 | environment: 21 | sdk: ">=3.5.0 <4.0.0" 22 | 23 | dependencies: 24 | archive: ^4.0.0 25 | checked_yaml: ^2.0.3 26 | collection: ^1.18.0 27 | convert: ^3.1.1 28 | crypto: ^3.0.5 29 | http: ^1.2.2 30 | json_annotation: ^4.9.0 31 | mason_logger: ^0.3.0 32 | meta: ^1.15.0 33 | mustache_template: ^2.0.0 34 | path: ^1.9.0 35 | pool: ^1.5.1 36 | pub_semver: ^2.1.4 37 | yaml: ^3.1.2 38 | 39 | dev_dependencies: 40 | build_runner: ^2.4.12 41 | build_verify: ^3.1.0 42 | build_version: ^2.1.1 43 | json_serializable: ^6.8.0 44 | mocktail: ^1.0.4 45 | test: ^1.25.8 46 | -------------------------------------------------------------------------------- /packages/mason/pubspec_overrides.yaml: -------------------------------------------------------------------------------- 1 | dependency_overrides: 2 | mason_logger: 3 | path: ../mason_logger 4 | -------------------------------------------------------------------------------- /packages/mason/test/bricks/custom_registry/brick.yaml: -------------------------------------------------------------------------------- 1 | name: custom_registry 2 | description: A Simple Template that should be published to a custom registry 3 | version: 0.1.0+1 4 | publish_to: https://custom.brickhub.dev 5 | -------------------------------------------------------------------------------- /packages/mason/test/bricks/loop/__brick__/main_{{#values}}{{{.}}}{{/values}}.txt: -------------------------------------------------------------------------------- 1 | {{#values}}{{..upperCase()}}{{/values}} -------------------------------------------------------------------------------- /packages/mason/test/bricks/loop/brick.yaml: -------------------------------------------------------------------------------- 1 | name: loop 2 | description: A new brick created with the Mason CLI. 3 | 4 | version: 0.1.0+1 5 | 6 | environment: 7 | mason: ^0.1.0 8 | 9 | vars: 10 | values: 11 | type: array 12 | values: 13 | - development 14 | - staging 15 | - production 16 | -------------------------------------------------------------------------------- /packages/mason/test/bricks/nested_conditional/__brick__/{{#generate}}{{#snakeCase}}{{{name}}}{{/snakeCase}}.txt{{/generate}}: -------------------------------------------------------------------------------- 1 | Hello {{name.titleCase()}} -------------------------------------------------------------------------------- /packages/mason/test/bricks/nested_conditional/brick.yaml: -------------------------------------------------------------------------------- 1 | name: nested_conditional 2 | description: A new brick created with the Mason CLI. 3 | 4 | version: 0.1.0+1 5 | 6 | environment: 7 | mason: ^0.1.0 8 | 9 | vars: 10 | name: 11 | type: string 12 | description: Your name 13 | default: Dash 14 | prompt: What is your name? 15 | generate: 16 | type: boolean 17 | description: Whether to generate a file 18 | prompt: Do you want to generate a file? 19 | -------------------------------------------------------------------------------- /packages/mason/test/bricks/no_registry/brick.yaml: -------------------------------------------------------------------------------- 1 | name: no_registry 2 | description: A Simple Template that cannot be published 3 | version: 0.1.0+1 4 | publish_to: none 5 | -------------------------------------------------------------------------------- /packages/mason/test/bundles/bundles.dart: -------------------------------------------------------------------------------- 1 | export 'greeting_bundle.dart'; 2 | export 'hooks_bundle.dart'; 3 | export 'photos_bundle.dart'; 4 | export 'relative_imports_bundle.dart'; 5 | -------------------------------------------------------------------------------- /packages/mason/test/bundles/greeting_bundle.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | // ignore_for_file: type=lint, implicit_dynamic_list_literal, implicit_dynamic_map_literal, inference_failure_on_collection_literal 3 | 4 | import 'package:mason/mason.dart'; 5 | 6 | final greetingBundle = MasonBundle.fromJson({ 7 | "files": [ 8 | {"path": "GREETINGS.md", "data": "SGkge3tuYW1lfX0h", "type": "text"} 9 | ], 10 | "hooks": [], 11 | "name": "greeting", 12 | "description": "A Simple Greeting Template", 13 | "version": "1.0.0", 14 | "vars": { 15 | "name": {"type": "string"} 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /packages/mason/test/bundles/hooks_bundle.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | // ignore_for_file: type=lint, implicit_dynamic_list_literal, implicit_dynamic_map_literal, inference_failure_on_collection_literal 3 | 4 | import 'package:mason/mason.dart'; 5 | 6 | final hooksBundle = MasonBundle.fromJson({ 7 | "files": [ 8 | {"path": "hooks.md", "data": "SGkge3tuYW1lfX0h", "type": "text"} 9 | ], 10 | "hooks": [ 11 | { 12 | "path": "post_gen.dart", 13 | "data": 14 | "aW1wb3J0ICdkYXJ0OmlvJztpbXBvcnQgJ3BhY2thZ2U6bWFzb24vbWFzb24uZGFydCc7dm9pZCBydW4oSG9va0NvbnRleHQgY29udGV4dCl7ZmluYWwgZmlsZT1GaWxlKCcucG9zdF9nZW4udHh0Jyk7ZmlsZS53cml0ZUFzU3RyaW5nU3luYygncG9zdF9nZW46ICR7Y29udGV4dC52YXJzWyduYW1lJ119Jyk7fQ==", 15 | "type": "text" 16 | }, 17 | { 18 | "path": "pre_gen.dart", 19 | "data": 20 | "aW1wb3J0ICdkYXJ0OmlvJztpbXBvcnQgJ3BhY2thZ2U6bWFzb24vbWFzb24uZGFydCc7dm9pZCBydW4oSG9va0NvbnRleHQgY29udGV4dCl7ZmluYWwgZmlsZT1GaWxlKCcucHJlX2dlbi50eHQnKTtmaWxlLndyaXRlQXNTdHJpbmdTeW5jKCdwcmVfZ2VuOiAke2NvbnRleHQudmFyc1snbmFtZSddfScpO30=", 21 | "type": "text" 22 | }, 23 | { 24 | "path": "pubspec.yaml", 25 | "data": 26 | "bmFtZTogaG9va3NfaG9va3MKCmVudmlyb25tZW50OgogIHNkazogIj49Mi4xMi4wIDwzLjAuMCIKCmRlcGVuZGVuY2llczoKICBtYXNvbjoKICAgIGdpdDoKICAgICAgdXJsOiBodHRwczovL2dpdGh1Yi5jb20vZmVsYW5nZWwvbWFzb24KICAgICAgcGF0aDogcGFja2FnZXMvbWFzb24K", 27 | "type": "text" 28 | } 29 | ], 30 | "name": "hooks", 31 | "description": "A Hooks Example Template", 32 | "version": "0.1.0+1", 33 | "environment": {"mason": "any"}, 34 | "vars": { 35 | "name": { 36 | "type": "string", 37 | "description": "Your name", 38 | "default": "Dash", 39 | "prompt": "What is your name?" 40 | } 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /packages/mason/test/bundles/photos_bundle.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | // ignore_for_file: type=lint, implicit_dynamic_list_literal, implicit_dynamic_map_literal, inference_failure_on_collection_literal 3 | 4 | import 'package:mason/mason.dart'; 5 | 6 | final photosBundle = MasonBundle.fromJson({ 7 | "files": [ 8 | { 9 | "path": "image.png", 10 | "data": 11 | "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=", 12 | "type": "binary" 13 | } 14 | ], 15 | "hooks": [], 16 | "name": "photos", 17 | "description": "A Photos Example Template", 18 | "version": "1.0.0", 19 | "vars": {} 20 | }); 21 | -------------------------------------------------------------------------------- /packages/mason/test/bundles/relative_imports_bundle.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | // ignore_for_file: type=lint, implicit_dynamic_list_literal, implicit_dynamic_map_literal, inference_failure_on_collection_literal 3 | 4 | import 'package:mason/mason.dart'; 5 | 6 | final relativeImportsBundle = MasonBundle.fromJson({ 7 | "files": [ 8 | {"path": ".gitkeep", "data": "", "type": "text"} 9 | ], 10 | "hooks": [ 11 | { 12 | "path": "post_gen.dart", 13 | "data": 14 | "aW1wb3J0ICdwYWNrYWdlOm1hc29uL21hc29uLmRhcnQnOwppbXBvcnQgJy4vc3JjL21haW4uZGFydCc7Cgp2b2lkIHJ1bihIb29rQ29udGV4dCBjb250ZXh0KSA9PiBwb3N0R2VuKGNvbnRleHQpOwo=", 15 | "type": "text" 16 | }, 17 | { 18 | "path": "pre_gen.dart", 19 | "data": 20 | "aW1wb3J0ICdwYWNrYWdlOm1hc29uL21hc29uLmRhcnQnOwppbXBvcnQgJy4vc3JjL21haW4uZGFydCc7Cgp2b2lkIHJ1bihIb29rQ29udGV4dCBjb250ZXh0KSA9PiBwcmVHZW4oY29udGV4dCk7Cg==", 21 | "type": "text" 22 | }, 23 | { 24 | "path": "pubspec.yaml", 25 | "data": 26 | "bmFtZTogcmVsYXRpdmVfaW1wb3J0c19ob29rcwoKZW52aXJvbm1lbnQ6CiAgc2RrOiAiPj0yLjEyLjAgPDMuMC4wIgoKZGVwZW5kZW5jaWVzOgogIG1hc29uOgogICAgZ2l0OgogICAgICB1cmw6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZWxhbmdlbC9tYXNvbgogICAgICBwYXRoOiBwYWNrYWdlcy9tYXNvbgo=", 27 | "type": "text" 28 | }, 29 | { 30 | "path": "src/main.dart", 31 | "data": 32 | "aW1wb3J0ICdkYXJ0OmlvJzsKaW1wb3J0ICdwYWNrYWdlOm1hc29uL21hc29uLmRhcnQnOwoKdm9pZCBwcmVHZW4oSG9va0NvbnRleHQgY29udGV4dCkgewogIEZpbGUoJy5wcmVfZ2VuLnR4dCcpLndyaXRlQXNTdHJpbmdTeW5jKCdwcmVfZ2VuOiAke2NvbnRleHQudmFyc1snbmFtZSddfScpOwp9Cgp2b2lkIHBvc3RHZW4oSG9va0NvbnRleHQgY29udGV4dCkgewogIEZpbGUoJy5wb3N0X2dlbi50eHQnKS53cml0ZUFzU3RyaW5nU3luYygncG9zdF9nZW46ICR7Y29udGV4dC52YXJzWyduYW1lJ119Jyk7Cn0K", 33 | "type": "text" 34 | } 35 | ], 36 | "name": "relative_imports", 37 | "description": "A Test Hook", 38 | "version": "0.1.0+1", 39 | "environment": {"mason": "any"}, 40 | "vars": {} 41 | }); 42 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/basic/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/basic/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason/test/fixtures/basic/brick.yaml: -------------------------------------------------------------------------------- 1 | name: basic_hook 2 | description: A basic Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/basic/hooks/post_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | 3 | void run(HookContext context) {} 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/basic/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | 3 | void run(HookContext context) {} 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/basic/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: basic_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/compile_exception/brick.yaml: -------------------------------------------------------------------------------- 1 | name: compile_exception_hook 2 | description: A Test Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/compile_exception/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | void run(HookContext context) {} 2 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/compile_exception/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: compile_exception_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/dependency_install_failure/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/dependency_install_failure/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason/test/fixtures/dependency_install_failure/brick.yaml: -------------------------------------------------------------------------------- 1 | name: dependency_install_failure_hook 2 | description: A Test Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/dependency_install_failure/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | 3 | void run(HookContext context) {} 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/dependency_install_failure/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dependency_install_failure_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | foo: 8 | path: ./foo 9 | mason: 10 | git: 11 | url: https://github.com/felangel/mason 12 | path: packages/mason 13 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/empty/brick.yaml: -------------------------------------------------------------------------------- 1 | name: empty 2 | description: An empty brick 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/execution_exception/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/execution_exception/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason/test/fixtures/execution_exception/brick.yaml: -------------------------------------------------------------------------------- 1 | name: unicode_hook 2 | description: A Test Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/execution_exception/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart';void run(HookContext context){throw Exception();} -------------------------------------------------------------------------------- /packages/mason/test/fixtures/execution_exception/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: execution_exception_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/hooks/__brick__/hooks.md: -------------------------------------------------------------------------------- 1 | Hi {{name}}! -------------------------------------------------------------------------------- /packages/mason/test/fixtures/hooks/brick.yaml: -------------------------------------------------------------------------------- 1 | name: hooks 2 | description: A Test Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/hooks/hooks/post_gen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:mason/mason.dart'; 3 | 4 | void run(HookContext context) { 5 | final file = File('.post_gen.txt'); 6 | file.writeAsStringSync('post_gen: ${context.vars['name']}'); 7 | } 8 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/hooks/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:mason/mason.dart'; 3 | 4 | void run(HookContext context) { 5 | final file = File('.pre_gen.txt'); 6 | file.writeAsStringSync('pre_gen: ${context.vars['name']}'); 7 | } 8 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/hooks/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: hooks_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | mason: 8 | path: ../../../../ 9 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/long_run/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/long_run/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason/test/fixtures/long_run/brick.yaml: -------------------------------------------------------------------------------- 1 | name: long_run_hook 2 | description: A Test Hook with a long formatted run method. 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/long_run/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | 3 | Future run( 4 | HookContext context, { 5 | Object? veryLongParameter, 6 | }) async {} 7 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/long_run/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: long_run_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/malformed_pubspec/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/malformed_pubspec/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason/test/fixtures/malformed_pubspec/brick.yaml: -------------------------------------------------------------------------------- 1 | name: malformed_pubspec 2 | description: A Test Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/malformed_pubspec/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart';void run(HookContext context){} -------------------------------------------------------------------------------- /packages/mason/test/fixtures/malformed_pubspec/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: malformed_pubspec_hooks -------------------------------------------------------------------------------- /packages/mason/test/fixtures/missing_run/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/missing_run/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason/test/fixtures/missing_run/brick.yaml: -------------------------------------------------------------------------------- 1 | name: missing_run_hook 2 | description: A Test Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/missing_run/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | void main(){} -------------------------------------------------------------------------------- /packages/mason/test/fixtures/missing_run/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: missing_run_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/programmatic_usage/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:mason/mason.dart'; 4 | import 'package:path/path.dart' as path; 5 | 6 | void main(List args) async { 7 | if (args.length != 2) return; 8 | final workingDirectory = args.first; 9 | final name = args.last; 10 | final brick = Brick.path(path.join('test', 'fixtures', 'hooks')); 11 | final generator = await MasonGenerator.fromBrick(brick); 12 | final target = DirectoryGeneratorTarget(Directory(workingDirectory)); 13 | final vars = {'name': name}; 14 | await generator.hooks.preGen(vars: vars, workingDirectory: workingDirectory); 15 | await generator.generate(target, vars: vars); 16 | await generator.hooks.postGen(vars: vars, workingDirectory: workingDirectory); 17 | } 18 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/relative_imports/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/relative_imports/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason/test/fixtures/relative_imports/brick.yaml: -------------------------------------------------------------------------------- 1 | name: relative_imports 2 | description: A Test Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/relative_imports/hooks/legacy/post_gen.dill: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/relative_imports/hooks/legacy/post_gen.dill -------------------------------------------------------------------------------- /packages/mason/test/fixtures/relative_imports/hooks/legacy/pre_gen.dill: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/relative_imports/hooks/legacy/pre_gen.dill -------------------------------------------------------------------------------- /packages/mason/test/fixtures/relative_imports/hooks/post_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | import './src/main.dart'; 3 | 4 | void run(HookContext context) => postGen(context); 5 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/relative_imports/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | import './src/main.dart'; 3 | 4 | void run(HookContext context) => preGen(context); 5 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/relative_imports/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: relative_imports_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/relative_imports/hooks/src/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:mason/mason.dart'; 3 | 4 | void preGen(HookContext context) { 5 | File('.pre_gen.txt').writeAsStringSync('pre_gen: ${context.vars['name']}'); 6 | } 7 | 8 | void postGen(HookContext context) { 9 | File('.post_gen.txt').writeAsStringSync('post_gen: ${context.vars['name']}'); 10 | } 11 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/run_exception/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/run_exception/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason/test/fixtures/run_exception/brick.yaml: -------------------------------------------------------------------------------- 1 | name: run_exception_hook 2 | description: A Test Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/run_exception/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: missing_function_body 2 | import 'package:mason/mason.dart';void run(HookContext context) -------------------------------------------------------------------------------- /packages/mason/test/fixtures/run_exception/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: run_exception_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/unicode_hook/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason/test/fixtures/unicode_hook/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason/test/fixtures/unicode_hook/brick.yaml: -------------------------------------------------------------------------------- 1 | name: unicode_hook 2 | description: A Test Hook 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason/test/fixtures/unicode_hook/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart';void run(HookContext context){'✨'.trim();} -------------------------------------------------------------------------------- /packages/mason/test/fixtures/unicode_hook/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: unicode_hook_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /packages/mason/test/src/brick_compatibility_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | void main() { 5 | BrickYaml getBrickYaml(String constraint) { 6 | return BrickYaml( 7 | name: 'example', 8 | description: 'example', 9 | version: '0.1.0', 10 | environment: BrickEnvironment(mason: constraint), 11 | ); 12 | } 13 | 14 | group('isBrickCompatibleWithMason', () { 15 | test('returns true when constraint is any', () { 16 | expect( 17 | isBrickCompatibleWithMason(getBrickYaml('any')), 18 | isTrue, 19 | ); 20 | }); 21 | 22 | test('returns true when constraint is ^{currentVersion}', () { 23 | expect( 24 | isBrickCompatibleWithMason(getBrickYaml('^$packageVersion')), 25 | isTrue, 26 | ); 27 | }); 28 | 29 | test('returns true when constraint is {currentVersion}', () { 30 | expect( 31 | isBrickCompatibleWithMason(getBrickYaml(packageVersion)), 32 | isTrue, 33 | ); 34 | }); 35 | 36 | test('returns true when constraint is ">={currentVersion}"', () { 37 | expect( 38 | isBrickCompatibleWithMason(getBrickYaml('>=$packageVersion')), 39 | isTrue, 40 | ); 41 | }); 42 | 43 | test('returns false when constraint is 0.0.0', () { 44 | expect( 45 | isBrickCompatibleWithMason(getBrickYaml('0.0.0')), 46 | isFalse, 47 | ); 48 | }); 49 | 50 | test('returns false when constraint is ^0.0.0', () { 51 | expect( 52 | isBrickCompatibleWithMason(getBrickYaml('^0.0.0')), 53 | isFalse, 54 | ); 55 | }); 56 | 57 | test('returns false when constraint is >=0.0.0 <0.0.1', () { 58 | expect( 59 | isBrickCompatibleWithMason(getBrickYaml('>=0.0.0 <0.0.1')), 60 | isFalse, 61 | ); 62 | }); 63 | }); 64 | } 65 | -------------------------------------------------------------------------------- /packages/mason/test/src/exception_test.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: prefer_const_constructors 2 | 3 | import 'package:mason/mason.dart'; 4 | import 'package:mason/src/bricks_json.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | group('Exception', () { 9 | group('MasonException', () { 10 | test('can be instantiated', () { 11 | const message = 'test message'; 12 | final exception = MasonException(message); 13 | expect(exception.message, equals(message)); 14 | }); 15 | 16 | test('overrides toString()', () { 17 | const message = 'test message'; 18 | final exception = MasonException(message); 19 | expect(exception.toString(), equals(message)); 20 | }); 21 | }); 22 | 23 | group('BrickResolveVersionException', () { 24 | test('can be instantiated', () { 25 | const message = 'test message'; 26 | final exception = BrickResolveVersionException(message); 27 | expect(exception.message, equals(message)); 28 | }); 29 | }); 30 | 31 | group('BrickUnsatisfiedVersionConstraint', () { 32 | test('can be instantiated', () { 33 | const message = 'test message'; 34 | final exception = BrickUnsatisfiedVersionConstraint(message); 35 | expect(exception.message, equals(message)); 36 | }); 37 | }); 38 | 39 | group('BrickNotFoundException', () { 40 | test('can be instantiated', () { 41 | const path = 'test path'; 42 | final exception = BrickNotFoundException(path); 43 | expect(exception.message, equals('Could not find brick at $path')); 44 | }); 45 | }); 46 | 47 | group('MasonYamlNameMismatch', () { 48 | test('has the correct message', () { 49 | const message = 'test message'; 50 | expect(MasonYamlNameMismatch(message).message, equals(message)); 51 | }); 52 | }); 53 | }); 54 | } 55 | -------------------------------------------------------------------------------- /packages/mason/test/src/git_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:mason/src/git.dart'; 4 | import 'package:test/test.dart'; 5 | 6 | void main() { 7 | group('Git', () { 8 | group('run', () { 9 | test('throws when operation fails', () async { 10 | expect( 11 | () => Git.run(['clone', 'https://github.com/felangel/masons']), 12 | throwsA(isA()), 13 | ); 14 | }); 15 | 16 | test('completes when operation succeeds', () async { 17 | expect(Git.run(['--version']), completes); 18 | }); 19 | }); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /packages/mason/test/src/mason_lock_json_test.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: prefer_const_constructors 2 | 3 | import 'package:mason/mason.dart'; 4 | import 'package:test/test.dart'; 5 | 6 | void main() { 7 | group('MasonLockJson', () { 8 | test('can be (de)serialized', () { 9 | final brickLocation = BrickLocation(path: '.'); 10 | final instance = MasonLockJson( 11 | bricks: {'example': brickLocation}, 12 | ); 13 | final result = MasonLockJson.fromJson(instance.toJson()); 14 | expect(result.bricks.length, equals(1)); 15 | expect(result.bricks.keys.first, equals('example')); 16 | expect( 17 | result.bricks.values.first, 18 | isA().having((b) => b.path, 'path', brickLocation.path), 19 | ); 20 | }); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /packages/mason_api/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | 5 | # Remove the following pattern if you wish to check in your lock file 6 | pubspec.lock 7 | 8 | # Conventional directory for build outputs 9 | build/ 10 | 11 | # Directory created by dartdoc 12 | doc/api/ 13 | 14 | # Temporary Files 15 | .tmp/ 16 | 17 | # Local Mason Files 18 | .mason/ 19 | 20 | # Test Related Files 21 | coverage/ 22 | .test_coverage.dart -------------------------------------------------------------------------------- /packages/mason_api/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.1.1 2 | 3 | - chore: fix `unintended_html_in_doc_comment` lint 4 | 5 | # 0.1.0 6 | 7 | - chore: bump to stable v0.1.0 🎉 8 | 9 | # 0.1.0-dev.12 10 | 11 | - deps: tighten dependency constraints ([#1400](https://github.com/felangel/mason/issues/1400)) 12 | - bumps the Dart SDK minimum version up to `3.5.0` 13 | 14 | # 0.1.0-dev.11 15 | 16 | - chore: run `dart fix --apply` 17 | - chore: use more strict analysis options 18 | - deps: upgrade to `mocktail ^1.0.0` 19 | - deps: allow latest `pkg:http` 20 | - chore: remove redundant parameter in default hosted uri 21 | - deps: bump `cli_util` from `0.3.5` to `0.4.0` 22 | 23 | # 0.1.0-dev.10 24 | 25 | - deps: upgrade to `Dart >=2.19` and `very_good_analysis ^4.0.0` 26 | 27 | # 0.1.0-dev.9 28 | 29 | - deps: upgrade to `Dart >=2.17` and `very_good_analysis ^3.1.0` 30 | 31 | # 0.1.0-dev.8 32 | 33 | - fix: `login` sets in-memory credentials 34 | 35 | # 0.1.0-dev.7 36 | 37 | - feat: add `close` 38 | - docs: add additional metadata to `pubspec.yaml` 39 | - chore: upgrade to `mocktail ^0.3.0` 40 | 41 | # 0.1.0-dev.6 42 | 43 | - refactor(deps): remove `pkg:universal_io` 44 | 45 | # 0.1.0-dev.5 46 | 47 | - feat: add `search` to `MasonApi` 48 | 49 | # 0.1.0-dev.4 50 | 51 | - feat: add `details` to `MasonApiException` 52 | - refactor: define internal `ErrorResponse` with `JsonSerializable` 53 | 54 | # 0.1.0-dev.3 55 | 56 | - chore: upgrade to Dart 2.16 57 | 58 | # 0.1.0-dev.2 59 | 60 | - feat: support for custom `hostedUri` 61 | 62 | # 0.1.0-dev.1 63 | 64 | - feat: export `MasonApi` 65 | - `login`, `logout`, `currentUser`, and `publish` support. 66 | -------------------------------------------------------------------------------- /packages/mason_api/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2024 Felix Angelov 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without restriction, 7 | including without limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of the Software, 9 | and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 | USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/mason_api/README.md: -------------------------------------------------------------------------------- 1 | # mason_api 2 | 3 | [![build](https://github.com/felangel/mason/workflows/mason_api/badge.svg)](https://github.com/felangel/mason/actions) 4 | [![coverage](https://raw.githubusercontent.com/felangel/mason/master/packages/mason_api/coverage_badge.svg)](https://github.com/felangel/mason/actions) 5 | [![Pub](https://img.shields.io/pub/v/mason_api.svg)](https://pub.dev/packages/mason) 6 | [![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT) 7 | 8 | A Dart API client used by [package:mason_cli](https://github.com/felangel/mason). 9 | 10 | ```dart 11 | import 'package:mason_api/mason_api.dart'; 12 | 13 | const email = 'my@email.com'; 14 | const password = 'top-secret!'; 15 | 16 | Future main() async { 17 | final masonApi = MasonApi(); 18 | 19 | final user = await masonApi.login(email: email, password: password); 20 | print('Logged in as ${user.email}!'); 21 | 22 | masonApi.logout(); 23 | print('Logged out!'); 24 | 25 | masonApi.close(); 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /packages/mason_api/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: ../../analysis_options.yaml 2 | analyzer: 3 | errors: 4 | todo: ignore 5 | exclude: 6 | - "example/main.dart" 7 | -------------------------------------------------------------------------------- /packages/mason_api/build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | builders: 4 | source_gen|combining_builder: 5 | options: 6 | ignore_for_file: 7 | - implicit_dynamic_parameter 8 | - require_trailing_commas 9 | - cast_nullable_to_non_nullable 10 | - lines_longer_than_80_chars 11 | json_serializable: 12 | options: 13 | checked: true 14 | field_rename: snake 15 | -------------------------------------------------------------------------------- /packages/mason_api/coverage_badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | coverage 16 | coverage 17 | 100% 18 | 100% 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/mason_api/example/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason_api/mason_api.dart'; 2 | 3 | const email = 'my@email.com'; 4 | const password = 't0pS3cret!'; // cspell:disable-line 5 | 6 | Future main() async { 7 | final masonApi = MasonApi(); 8 | 9 | final user = await masonApi.login(email: email, password: password); 10 | print('Logged in as ${user.email}!'); 11 | 12 | masonApi.logout(); 13 | print('Logged out!'); 14 | 15 | masonApi.close(); 16 | } 17 | -------------------------------------------------------------------------------- /packages/mason_api/lib/mason_api.dart: -------------------------------------------------------------------------------- 1 | /// A Dart API client used by the Mason CLI. 2 | /// 3 | /// Get started at [https://github.com/felangel/mason](https://github.com/felangel/mason) 🧱 4 | library mason_api; 5 | 6 | export 'src/mason_api.dart' 7 | show 8 | MasonApi, 9 | MasonApiException, 10 | MasonApiLoginFailure, 11 | MasonApiPublishFailure; 12 | export 'src/models/models.dart' show BrickSearchResult, User; 13 | -------------------------------------------------------------------------------- /packages/mason_api/lib/src/jwt_decode.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// Jwt Utilities 4 | class Jwt { 5 | /// Decode and extract claims from a JWT token. 6 | static Map? decodeClaims(String value) { 7 | final parts = value.split('.'); 8 | if (parts.length != 3) return null; 9 | try { 10 | return _decodePart(parts[1]); 11 | } catch (_) {} 12 | return null; 13 | } 14 | } 15 | 16 | Map _decodePart(String part) { 17 | final normalized = base64.normalize(part); 18 | final base64Decoded = base64.decode(normalized); 19 | final utf8Decoded = utf8.decode(base64Decoded); 20 | final jsonDecoded = json.decode(utf8Decoded) as Map; 21 | return jsonDecoded; 22 | } 23 | -------------------------------------------------------------------------------- /packages/mason_api/lib/src/models/brick_search_result.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'brick_search_result.g.dart'; 4 | 5 | /// {@template brick_search_result} 6 | /// Brick search result details from brickhub.dev. 7 | /// {@endtemplate} 8 | @JsonSerializable(createToJson: false) 9 | class BrickSearchResult { 10 | /// {@macro brick_search_result} 11 | const BrickSearchResult({ 12 | required this.name, 13 | required this.description, 14 | required this.publisher, 15 | required this.version, 16 | required this.createdAt, 17 | required this.downloads, 18 | }); 19 | 20 | /// Converts a [Map] to [BrickSearchResult]. 21 | factory BrickSearchResult.fromJson(Map json) => 22 | _$BrickSearchResultFromJson(json); 23 | 24 | /// The name of the brick. 25 | final String name; 26 | 27 | /// The brick description. 28 | final String description; 29 | 30 | /// The email of the brick publisher. 31 | final String publisher; 32 | 33 | /// The latest published version of the brick. 34 | final String version; 35 | 36 | /// The date when the brick was created. 37 | final DateTime createdAt; 38 | 39 | /// The number of times the brick has been downloaded. 40 | final int downloads; 41 | } 42 | -------------------------------------------------------------------------------- /packages/mason_api/lib/src/models/brick_search_result.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | // ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars 4 | 5 | part of 'brick_search_result.dart'; 6 | 7 | // ************************************************************************** 8 | // JsonSerializableGenerator 9 | // ************************************************************************** 10 | 11 | BrickSearchResult _$BrickSearchResultFromJson(Map json) => 12 | $checkedCreate( 13 | 'BrickSearchResult', 14 | json, 15 | ($checkedConvert) { 16 | final val = BrickSearchResult( 17 | name: $checkedConvert('name', (v) => v as String), 18 | description: $checkedConvert('description', (v) => v as String), 19 | publisher: $checkedConvert('publisher', (v) => v as String), 20 | version: $checkedConvert('version', (v) => v as String), 21 | createdAt: 22 | $checkedConvert('created_at', (v) => DateTime.parse(v as String)), 23 | downloads: $checkedConvert('downloads', (v) => (v as num).toInt()), 24 | ); 25 | return val; 26 | }, 27 | fieldKeyMap: const {'createdAt': 'created_at'}, 28 | ); 29 | -------------------------------------------------------------------------------- /packages/mason_api/lib/src/models/credentials.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'credentials.g.dart'; 4 | 5 | /// {@template credentials} 6 | /// Credentials for an authenticated user. 7 | /// {@endtemplate} 8 | @JsonSerializable() 9 | class Credentials { 10 | /// {@macro credentials} 11 | const Credentials({ 12 | required this.accessToken, 13 | required this.refreshToken, 14 | required this.expiresAt, 15 | required this.tokenType, 16 | }); 17 | 18 | /// Converts a [Map] to [Credentials] from a token response. 19 | factory Credentials.fromTokenResponse(Map json) { 20 | return Credentials( 21 | accessToken: json['access_token'] as String, 22 | refreshToken: json['refresh_token'] as String, 23 | expiresAt: DateTime.now() 24 | .toUtc() 25 | .add(Duration(seconds: int.parse(json['expires_in'] as String))), 26 | tokenType: json['token_type'] as String, 27 | ); 28 | } 29 | 30 | /// Converts a [Map] to an instance of [Credentials]. 31 | factory Credentials.fromJson(Map json) => 32 | _$CredentialsFromJson(json); 33 | 34 | /// The access token. 35 | final String accessToken; 36 | 37 | /// The refresh token. 38 | final String refreshToken; 39 | 40 | /// When the token expires. 41 | final DateTime expiresAt; 42 | 43 | /// The token type (usually 'Bearer'). 44 | final String tokenType; 45 | 46 | /// Converts an instance of [Credentials] to a [Map]. 47 | Map toJson() => _$CredentialsToJson(this); 48 | } 49 | -------------------------------------------------------------------------------- /packages/mason_api/lib/src/models/credentials.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | // ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars 4 | 5 | part of 'credentials.dart'; 6 | 7 | // ************************************************************************** 8 | // JsonSerializableGenerator 9 | // ************************************************************************** 10 | 11 | Credentials _$CredentialsFromJson(Map json) => $checkedCreate( 12 | 'Credentials', 13 | json, 14 | ($checkedConvert) { 15 | final val = Credentials( 16 | accessToken: $checkedConvert('access_token', (v) => v as String), 17 | refreshToken: $checkedConvert('refresh_token', (v) => v as String), 18 | expiresAt: 19 | $checkedConvert('expires_at', (v) => DateTime.parse(v as String)), 20 | tokenType: $checkedConvert('token_type', (v) => v as String), 21 | ); 22 | return val; 23 | }, 24 | fieldKeyMap: const { 25 | 'accessToken': 'access_token', 26 | 'refreshToken': 'refresh_token', 27 | 'expiresAt': 'expires_at', 28 | 'tokenType': 'token_type' 29 | }, 30 | ); 31 | 32 | Map _$CredentialsToJson(Credentials instance) => 33 | { 34 | 'access_token': instance.accessToken, 35 | 'refresh_token': instance.refreshToken, 36 | 'expires_at': instance.expiresAt.toIso8601String(), 37 | 'token_type': instance.tokenType, 38 | }; 39 | -------------------------------------------------------------------------------- /packages/mason_api/lib/src/models/error_response.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'error_response.g.dart'; 4 | 5 | /// {@template error_response} 6 | /// Standard error response body from the Mason API. 7 | /// {@endtemplate} 8 | @JsonSerializable(createToJson: false) 9 | class ErrorResponse { 10 | /// {@macro error_response} 11 | const ErrorResponse({ 12 | required this.code, 13 | required this.message, 14 | this.details, 15 | }); 16 | 17 | /// Converts a [Map] to [ErrorResponse]. 18 | factory ErrorResponse.fromJson(Map json) => 19 | _$ErrorResponseFromJson(json); 20 | 21 | /// The unique error code. 22 | final String code; 23 | 24 | /// Human-readable error message. 25 | final String message; 26 | 27 | /// Optional details associated with the error. 28 | final String? details; 29 | } 30 | -------------------------------------------------------------------------------- /packages/mason_api/lib/src/models/error_response.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | // ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars 4 | 5 | part of 'error_response.dart'; 6 | 7 | // ************************************************************************** 8 | // JsonSerializableGenerator 9 | // ************************************************************************** 10 | 11 | ErrorResponse _$ErrorResponseFromJson(Map json) => 12 | $checkedCreate( 13 | 'ErrorResponse', 14 | json, 15 | ($checkedConvert) { 16 | final val = ErrorResponse( 17 | code: $checkedConvert('code', (v) => v as String), 18 | message: $checkedConvert('message', (v) => v as String), 19 | details: $checkedConvert('details', (v) => v as String?), 20 | ); 21 | return val; 22 | }, 23 | ); 24 | -------------------------------------------------------------------------------- /packages/mason_api/lib/src/models/models.dart: -------------------------------------------------------------------------------- 1 | export 'brick_search_result.dart'; 2 | export 'credentials.dart'; 3 | export 'error_response.dart'; 4 | export 'user.dart'; 5 | -------------------------------------------------------------------------------- /packages/mason_api/lib/src/models/user.dart: -------------------------------------------------------------------------------- 1 | /// {@template user} 2 | /// A mason user account. 3 | /// {@endtemplate} 4 | class User { 5 | /// {@macro user} 6 | const User({ 7 | required this.email, 8 | required this.emailVerified, 9 | }); 10 | 11 | /// The user's email address. 12 | final String email; 13 | 14 | /// Whether the user's email address has been verified. 15 | final bool emailVerified; 16 | } 17 | -------------------------------------------------------------------------------- /packages/mason_api/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mason_api 2 | description: A Dart API client used by the Mason CLI (package:mason_cli). 3 | version: 0.1.1 4 | homepage: https://github.com/felangel/mason 5 | repository: https://github.com/felangel/mason 6 | issue_tracker: https://github.com/felangel/mason/issues 7 | documentation: https://github.com/felangel/mason/tree/master/packages/mason_api#readme 8 | topics: [mason, template, generator] 9 | funding: [https://github.com/sponsors/felangel] 10 | 11 | environment: 12 | sdk: ^3.5.4 13 | 14 | dependencies: 15 | cli_util: ^0.4.1 16 | http: ^1.2.2 17 | json_annotation: ^4.9.0 18 | meta: ^1.15.0 19 | path: ^1.9.0 20 | platform: ^3.1.5 21 | 22 | dev_dependencies: 23 | build_runner: ^2.4.12 24 | json_serializable: ^6.8.0 25 | mocktail: ^1.0.4 26 | test: ^1.25.8 27 | -------------------------------------------------------------------------------- /packages/mason_api/test/src/jwt_decode_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason_api/src/jwt_decode.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | void main() { 5 | const token = // cspell:disable-next-line 6 | '''eyJhbGciOiJSUzI1NiIsImN0eSI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAZW1haWwuY29tIn0.pD47BhF3MBLyIpfsgWCzP9twzC1HJxGukpcR36DqT6yfiOMHTLcjDbCjRLAnklWEHiT0BQTKTfhs8IousU90Fm5bVKObudfKu8pP5iZZ6Ls4ohDjTrXky9j3eZpZjwv8CnttBVgRfMJG-7YASTFRYFcOLUpnb4Zm5R6QdoCDUYg'''; 7 | group('Jwt', () { 8 | group('decodeClaims', () { 9 | test('returns null jwt does not contain 3 segments', () { 10 | expect(Jwt.decodeClaims('invalid'), isNull); 11 | }); 12 | 13 | test('returns null when jwt payload segment is malformed', () { 14 | expect(Jwt.decodeClaims('this.is.invalid'), isNull); 15 | }); 16 | 17 | test('returns correct claims when jwt payload segment is valid', () { 18 | expect(Jwt.decodeClaims(token), equals({'email': 'test@email.com'})); 19 | }); 20 | }); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /packages/mason_cli/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | # Remove the following pattern if you wish to check in your lock file 5 | pubspec.lock 6 | 7 | # Conventional directory for build outputs 8 | build/ 9 | 10 | # Directory created by dartdoc 11 | doc/api/ 12 | 13 | # Temporary Files 14 | .tmp/ 15 | 16 | # Local Mason Files 17 | .mason/ 18 | mason-lock.json 19 | 20 | # Test Related Files 21 | coverage/ 22 | test/fixtures/.*/ 23 | 24 | # Exceptions to the above rules 25 | !test/fixtures/*/.mason/ 26 | !test/fixtures/*/mason-lock.json 27 | -------------------------------------------------------------------------------- /packages/mason_cli/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2024 Felix Angelov 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without restriction, 7 | including without limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of the Software, 9 | and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 | USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/mason_cli/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: ../../analysis_options.yaml 2 | analyzer: 3 | exclude: 4 | - "test/.test_coverage.dart" 5 | - "test/fixtures/**" 6 | - "test/bricks/**" 7 | - "**/*.g.dart" 8 | - "**/version.dart" 9 | linter: 10 | rules: 11 | no_leading_underscores_for_local_identifiers: false 12 | -------------------------------------------------------------------------------- /packages/mason_cli/bin/mason.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:mason_cli/src/command_runner.dart'; 4 | 5 | Future main(List args) async { 6 | await flushThenExit(await MasonCommandRunner().run(args)); 7 | } 8 | 9 | /// Flushes the stdout and stderr streams, then exits the program with the given 10 | /// status code. 11 | /// 12 | /// This returns a Future that will never complete, since the program will have 13 | /// exited already. This is useful to prevent Future chains from proceeding 14 | /// after you've decided to exit. 15 | Future flushThenExit(int status) { 16 | return Future.wait([stdout.close(), stderr.close()]) 17 | .then((_) => exit(status)); 18 | } 19 | -------------------------------------------------------------------------------- /packages/mason_cli/coverage_badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | coverage 16 | coverage 17 | 100% 18 | 100% 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/mason_cli/dart_test.yaml: -------------------------------------------------------------------------------- 1 | tags: 2 | pull-request-only: 3 | skip: "Should only be run during pull request" 4 | -------------------------------------------------------------------------------- /packages/mason_cli/example/README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | ## Basic 4 | 5 | Run the following command in the current directory: 6 | 7 | ```sh 8 | $ mason get # only first time 9 | $ mason make greeting --name Felix 10 | ``` 11 | 12 | `GREETINGS.md` should be created in the current directory with the following contents: 13 | 14 | ```md 15 | # Greetings Felix! 16 | ``` 17 | 18 | ## Loops and JSON 19 | 20 | Run the following command in the current directory: 21 | 22 | ```sh 23 | $ mason get # only first time 24 | $ mason make todos -c todos.json 25 | ``` 26 | 27 | `TODOS.md` should be created in the current directory with the following contents: 28 | 29 | ```md 30 | # TODOS 31 | 32 | - [x] Eat 33 | - [x] Code 34 | - [ ] Sleep 35 | ``` 36 | -------------------------------------------------------------------------------- /packages/mason_cli/example/mason.yaml: -------------------------------------------------------------------------------- 1 | bricks: 2 | app_icon: 3 | path: ../../../bricks/app_icon 4 | bio: 5 | path: ../../../bricks/bio 6 | documentation: 7 | path: ../../../bricks/documentation 8 | greeting: 9 | path: ../../../bricks/greeting 10 | hello_world: 11 | path: ../../../bricks/hello_world 12 | hooks: 13 | path: ../../../bricks/hooks 14 | legacy: 15 | path: ../../../bricks/legacy 16 | favorite_languages: 17 | path: ../../../bricks/favorite_languages 18 | plugin: 19 | path: ../../../bricks/plugin 20 | random_color: 21 | path: ../../../bricks/random_color 22 | simple: 23 | path: ../../../bricks/simple 24 | todos: 25 | path: ../../../bricks/todos 26 | widget: 27 | path: ../../../bricks/widget 28 | -------------------------------------------------------------------------------- /packages/mason_cli/example/todos.json: -------------------------------------------------------------------------------- 1 | { 2 | "todos": [ 3 | { "todo": "Eat", "done": true }, 4 | { "todo": "Code", "done": true }, 5 | { "todo": "Sleep", "done": false } 6 | ], 7 | "developers": [{ "name": "Alex" }, { "name": "Sam" }, { "name": "Jen" }] 8 | } 9 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/mason_cli.dart: -------------------------------------------------------------------------------- 1 | /// A Dart template generator which helps teams 2 | /// generate files quickly and consistently. 3 | /// 4 | /// ```sh 5 | /// # Activate mason 6 | /// dart pub global activate mason_cli 7 | /// 8 | /// # See usage 9 | /// mason --help 10 | /// ``` 11 | /// 12 | /// Get started at [https://github.com/felangel/mason](https://github.com/felangel/mason) 🧱 13 | library mason_cli; 14 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/commands/cache.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | import 'package:mason_cli/src/command.dart'; 3 | 4 | /// {@template cache_command} 5 | /// `mason cache` command includes several subcommands. 6 | /// {@endtemplate} 7 | class CacheCommand extends MasonCommand { 8 | /// {@macro cache_command} 9 | CacheCommand({Logger? logger}) : super(logger: logger) { 10 | addSubcommand(ClearCacheCommand(logger: logger)); 11 | } 12 | 13 | @override 14 | final String description = 'Interact with mason cache.'; 15 | 16 | @override 17 | final String name = 'cache'; 18 | } 19 | 20 | /// {@template cache_command} 21 | /// `mason cache clear` command which clears all local bricks. 22 | /// {@endtemplate} 23 | class ClearCacheCommand extends MasonCommand { 24 | /// {@macro cache_command} 25 | ClearCacheCommand({super.logger}); 26 | 27 | @override 28 | final String description = 'Clears the mason cache.'; 29 | 30 | @override 31 | final String name = 'clear'; 32 | 33 | @override 34 | Future run() async { 35 | final progress = logger.progress('Clearing cache'); 36 | 37 | localBricksJson?.clear(); 38 | try { 39 | BricksJson.rootDir.deleteSync(recursive: true); 40 | } catch (_) {} 41 | 42 | progress.complete('Cache cleared'); 43 | return ExitCode.success.code; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/commands/commands.dart: -------------------------------------------------------------------------------- 1 | export 'add.dart'; 2 | export 'bundle.dart'; 3 | export 'cache.dart'; 4 | export 'get.dart'; 5 | export 'init.dart'; 6 | export 'list.dart'; 7 | export 'login.dart'; 8 | export 'logout.dart'; 9 | export 'make.dart'; 10 | export 'new.dart'; 11 | export 'publish.dart'; 12 | export 'remove.dart'; 13 | export 'search.dart'; 14 | export 'unbundle.dart'; 15 | export 'update.dart'; 16 | export 'upgrade.dart'; 17 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/commands/get.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | import 'package:mason_cli/src/command.dart'; 3 | import 'package:mason_cli/src/install_brick.dart'; 4 | 5 | /// {@template get_command} 6 | /// `mason get` command which gets all bricks. 7 | /// {@endtemplate} 8 | class GetCommand extends MasonCommand with InstallBrickMixin { 9 | /// {@macro get_command} 10 | GetCommand({super.logger}); 11 | 12 | @override 13 | final String description = 'Gets all bricks in the nearest mason.yaml.'; 14 | 15 | @override 16 | final String name = 'get'; 17 | 18 | @override 19 | Future run() async { 20 | final progress = logger.progress('Getting bricks'); 21 | try { 22 | await getBricks(); 23 | } catch (_) { 24 | progress.fail(); 25 | rethrow; 26 | } 27 | progress.complete('Got bricks'); 28 | return ExitCode.success.code; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/commands/init.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | import 'package:mason_cli/src/command.dart'; 3 | import 'package:mason_cli/src/install_brick.dart'; 4 | 5 | /// {@template init_command} 6 | /// `mason init` command which initializes a new `mason.yaml`. 7 | /// {@endtemplate} 8 | class InitCommand extends MasonCommand with InstallBrickMixin { 9 | /// {@macro init_command} 10 | InitCommand({super.logger}); 11 | 12 | @override 13 | final String description = 'Initialize mason in the current directory.'; 14 | 15 | @override 16 | final String name = 'init'; 17 | 18 | @override 19 | Future run() async { 20 | if (masonInitialized) { 21 | logger.err('Existing ${MasonYaml.file} at ${localMasonYamlFile.path}'); 22 | return ExitCode.usage.code; 23 | } 24 | final progress = logger.progress('Initializing'); 25 | final target = DirectoryGeneratorTarget(cwd); 26 | final generator = _MasonYamlGenerator(); 27 | await generator.generate( 28 | target, 29 | vars: {'name': '{{name}}'}, 30 | logger: logger, 31 | ); 32 | 33 | progress.complete('Generated 1 file.'); 34 | logger.flush((message) => logger.info(darkGray.wrap(message))); 35 | return ExitCode.success.code; 36 | } 37 | } 38 | 39 | class _MasonYamlGenerator extends MasonGenerator { 40 | _MasonYamlGenerator() 41 | : super( 42 | '__mason_init__', 43 | 'Initialize a new ${MasonYaml.file}', 44 | files: [TemplateFile(MasonYaml.file, _masonYamlContent)], 45 | ); 46 | 47 | static const _masonYamlContent = ''' 48 | # Register bricks which can be consumed via the Mason CLI. 49 | # Run "mason get" to install all registered bricks. 50 | # To learn more, visit https://docs.brickhub.dev. 51 | bricks: 52 | # Bricks can be imported via version constraint from a registry. 53 | # Uncomment the following line to import the "hello" brick from BrickHub. 54 | # hello: 0.1.0+2 55 | # Bricks can also be imported via remote git url. 56 | # Uncomment the following lines to import the "widget" brick from git. 57 | # widget: 58 | # git: 59 | # url: https://github.com/felangel/mason.git 60 | # path: bricks/widget 61 | '''; 62 | } 63 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/commands/login.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart' hide packageVersion; 2 | import 'package:mason_api/mason_api.dart'; 3 | import 'package:mason_cli/src/command.dart'; 4 | import 'package:mason_cli/src/command_runner.dart'; 5 | 6 | /// {@template login_command} 7 | /// `mason login` command which allows users to authenticate. 8 | /// {@endtemplate} 9 | class LoginCommand extends MasonCommand { 10 | /// {@macro login_command} 11 | LoginCommand({super.logger, MasonApiBuilder? masonApiBuilder}) 12 | : _masonApiBuilder = masonApiBuilder ?? MasonApi.new; 13 | 14 | final MasonApiBuilder _masonApiBuilder; 15 | 16 | @override 17 | final String description = 'Log into brickhub.dev.'; 18 | 19 | @override 20 | final String name = 'login'; 21 | 22 | @override 23 | Future run() async { 24 | final masonApi = _masonApiBuilder(); 25 | final user = masonApi.currentUser; 26 | if (user != null) { 27 | logger 28 | ..info('You are already logged in as <${user.email}>') 29 | ..info("Run 'mason logout' to log out and try again."); 30 | return ExitCode.success.code; 31 | } 32 | 33 | final email = logger.prompt('email:'); 34 | final password = logger.prompt('password:', hidden: true); 35 | 36 | final progress = logger.progress('Logging into brickhub.dev'); 37 | try { 38 | final user = await masonApi.login(email: email, password: password); 39 | progress.complete('Logged into brickhub.dev'); 40 | logger.success('You are now logged in as <${user.email}>'); 41 | return ExitCode.success.code; 42 | } on MasonApiLoginFailure catch (error) { 43 | progress.fail(); 44 | logger.err(error.message); 45 | return ExitCode.software.code; 46 | } finally { 47 | masonApi.close(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/commands/logout.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart' hide packageVersion; 2 | import 'package:mason_api/mason_api.dart'; 3 | import 'package:mason_cli/src/command.dart'; 4 | import 'package:mason_cli/src/command_runner.dart'; 5 | 6 | /// {@template logout_command} 7 | /// `mason logout` command which allows users to log out. 8 | /// {@endtemplate} 9 | class LogoutCommand extends MasonCommand { 10 | /// {@macro logout_command} 11 | LogoutCommand({super.logger, MasonApiBuilder? masonApiBuilder}) 12 | : _masonApiBuilder = masonApiBuilder ?? MasonApi.new; 13 | 14 | final MasonApiBuilder _masonApiBuilder; 15 | 16 | @override 17 | final String description = 'Log out of brickhub.dev.'; 18 | 19 | @override 20 | final String name = 'logout'; 21 | 22 | @override 23 | Future run() async { 24 | final masonApi = _masonApiBuilder(); 25 | final user = masonApi.currentUser; 26 | if (user == null) { 27 | logger.info('You are already logged out.'); 28 | masonApi.close(); 29 | return ExitCode.success.code; 30 | } 31 | 32 | final progress = logger.progress('Logging out of brickhub.dev.'); 33 | try { 34 | masonApi.logout(); 35 | progress.complete('Logged out of brickhub.dev'); 36 | return ExitCode.success.code; 37 | } catch (error) { 38 | progress.fail(); 39 | logger.err('$error'); 40 | return ExitCode.software.code; 41 | } finally { 42 | masonApi.close(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/commands/remove.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:mason/mason.dart'; 4 | import 'package:mason_cli/src/command.dart'; 5 | 6 | /// {@template remove_command} 7 | /// `mason remove` command which removes a brick. 8 | /// {@endtemplate} 9 | class RemoveCommand extends MasonCommand { 10 | /// {@macro remove_command} 11 | RemoveCommand({super.logger}) { 12 | argParser.addFlag( 13 | 'global', 14 | abbr: 'g', 15 | help: 'Removes the brick globally.', 16 | ); 17 | } 18 | 19 | @override 20 | final String description = 'Removes a brick.'; 21 | 22 | @override 23 | final String name = 'remove'; 24 | 25 | @override 26 | Future run() async { 27 | if (results.rest.isEmpty) { 28 | usageException('name of the brick is required.'); 29 | } 30 | 31 | final brickName = results.rest.first; 32 | final isGlobal = results['global'] == true; 33 | final bricksJson = isGlobal ? globalBricksJson : localBricksJson; 34 | final masonYaml = isGlobal ? globalMasonYaml : localMasonYaml; 35 | final brickLocation = masonYaml.bricks[brickName]; 36 | if (bricksJson == null || brickLocation == null) { 37 | usageException('no brick named $brickName was found'); 38 | } 39 | 40 | final masonLockJsonFile = 41 | isGlobal ? globalMasonLockJsonFile : localMasonLockJsonFile; 42 | final masonLockJson = isGlobal ? globalMasonLockJson : localMasonLockJson; 43 | 44 | final masonYamlFile = isGlobal ? globalMasonYamlFile : localMasonYamlFile; 45 | final progress = logger.progress('Removing $brickName'); 46 | try { 47 | bricksJson.remove(Brick(name: brickName, location: brickLocation)); 48 | final bricks = Map.of(masonYaml.bricks) 49 | ..removeWhere((key, value) => key == brickName); 50 | 51 | masonYamlFile.writeAsStringSync(Yaml.encode(MasonYaml(bricks).toJson())); 52 | 53 | await bricksJson.flush(); 54 | 55 | if (masonLockJson.bricks.containsKey(brickName)) { 56 | final lockedBricks = {...masonLockJson.bricks} 57 | ..removeWhere((key, value) => key == brickName); 58 | await masonLockJsonFile.writeAsString( 59 | json.encode(MasonLockJson(bricks: lockedBricks).toJson()), 60 | ); 61 | } 62 | 63 | progress.complete('Removed $brickName'); 64 | } catch (_) { 65 | progress.fail(); 66 | rethrow; 67 | } 68 | 69 | return ExitCode.success.code; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/commands/update.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:mason/mason.dart' hide packageVersion; 4 | import 'package:mason_cli/src/command.dart'; 5 | import 'package:mason_cli/src/command_runner.dart'; 6 | import 'package:mason_cli/src/version.dart'; 7 | import 'package:pub_updater/pub_updater.dart'; 8 | 9 | /// {@template update_command} 10 | /// `mason update` command which updates mason. 11 | /// {@endtemplate} 12 | class UpdateCommand extends MasonCommand { 13 | /// {@macro update_command} 14 | UpdateCommand({ 15 | required PubUpdater pubUpdater, 16 | super.logger, 17 | }) : _pubUpdater = pubUpdater; 18 | 19 | final PubUpdater _pubUpdater; 20 | 21 | @override 22 | final String description = 'Update mason.'; 23 | 24 | @override 25 | final String name = 'update'; 26 | 27 | @override 28 | Future run() async { 29 | final updateCheckProgress = logger.progress('Checking for updates'); 30 | late final String latestVersion; 31 | try { 32 | latestVersion = await _pubUpdater.getLatestVersion(packageName); 33 | } catch (error) { 34 | updateCheckProgress.fail(); 35 | logger.err('$error'); 36 | return ExitCode.software.code; 37 | } 38 | updateCheckProgress.complete('Checked for updates'); 39 | 40 | final isUpToDate = packageVersion == latestVersion; 41 | if (isUpToDate) { 42 | logger.info('mason is already at the latest version.'); 43 | return ExitCode.success.code; 44 | } 45 | 46 | final progress = logger.progress('Updating to $latestVersion'); 47 | late final ProcessResult result; 48 | try { 49 | result = await _pubUpdater.update( 50 | packageName: packageName, 51 | versionConstraint: latestVersion, 52 | ); 53 | } catch (error) { 54 | progress.fail(); 55 | logger.err('$error'); 56 | return ExitCode.software.code; 57 | } 58 | 59 | if (result.exitCode != ExitCode.success.code) { 60 | progress.fail('Unable to update to $latestVersion'); 61 | logger.err('${result.stderr}'); 62 | return ExitCode.software.code; 63 | } 64 | 65 | progress.complete('Updated to $latestVersion'); 66 | 67 | return ExitCode.success.code; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/commands/upgrade.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | import 'package:mason_cli/src/command.dart'; 3 | import 'package:mason_cli/src/install_brick.dart'; 4 | 5 | /// {@template upgrade_command} 6 | /// `mason upgrade` command which upgrades bricks to their latest versions. 7 | /// {@endtemplate} 8 | class UpgradeCommand extends MasonCommand with InstallBrickMixin { 9 | /// {@macro upgrade_command} 10 | UpgradeCommand({super.logger}) { 11 | argParser.addFlag( 12 | 'global', 13 | abbr: 'g', 14 | help: 'Upgrades globally installed bricks.', 15 | ); 16 | } 17 | 18 | @override 19 | final String description = 'Upgrade bricks to their latest versions.'; 20 | 21 | @override 22 | final String name = 'upgrade'; 23 | 24 | @override 25 | Future run() async { 26 | final isGlobal = results['global'] == true; 27 | final progress = logger.progress('Upgrading bricks'); 28 | try { 29 | await getBricks(upgrade: true, global: isGlobal); 30 | } catch (_) { 31 | progress.fail(); 32 | rethrow; 33 | } 34 | progress.complete('Upgraded bricks'); 35 | return ExitCode.success.code; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/mason_cli/lib/src/version.dart: -------------------------------------------------------------------------------- 1 | // Generated code. Do not modify. 2 | const packageVersion = '0.1.2'; 3 | -------------------------------------------------------------------------------- /packages/mason_cli/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mason_cli 2 | description: > 3 | Mason CLI allows developers to create and consume reusable templates called bricks. 4 | version: 0.1.2 5 | homepage: https://github.com/felangel/mason 6 | repository: https://github.com/felangel/mason 7 | issue_tracker: https://github.com/felangel/mason/issues 8 | documentation: https://docs.brickhub.dev 9 | topics: [mason, cli, template, generator] 10 | funding: [https://github.com/sponsors/felangel] 11 | 12 | environment: 13 | sdk: ^3.5.4 14 | 15 | dependencies: 16 | args: ^2.5.0 17 | checked_yaml: ^2.0.3 18 | cli_completion: ^0.5.1 19 | mason: ^0.1.0 20 | mason_api: ^0.1.0 21 | meta: ^1.15.0 22 | path: ^1.9.0 23 | pub_updater: ^0.5.0 24 | watcher: ^1.1.0 25 | 26 | dev_dependencies: 27 | build_runner: ^2.4.12 28 | build_verify: ^3.1.0 29 | build_version: ^2.1.1 30 | collection: ^1.19.0 31 | mocktail: ^1.0.4 32 | test: ^1.25.8 33 | 34 | executables: 35 | mason: 36 | -------------------------------------------------------------------------------- /packages/mason_cli/pubspec_overrides.yaml: -------------------------------------------------------------------------------- 1 | dependency_overrides: 2 | mason: 3 | path: ../mason 4 | mason_api: 5 | path: ../mason_api 6 | mason_logger: 7 | path: ../mason_logger 8 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/array_no_choices/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason_cli/test/bricks/array_no_choices/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/array_no_choices/brick.yaml: -------------------------------------------------------------------------------- 1 | name: array_no_choices 2 | description: A new brick created with the Mason CLI. 3 | 4 | version: 0.1.0+1 5 | 6 | environment: 7 | mason: ^0.1.1 8 | 9 | vars: 10 | colors: 11 | type: array 12 | description: Your favorite colors 13 | prompt: What are your favorite colors? 14 | values: 15 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/compilation_error/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason_cli/test/bricks/compilation_error/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/compilation_error/brick.yaml: -------------------------------------------------------------------------------- 1 | name: compilation_error 2 | description: A test brick 3 | version: 0.1.0+1 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/compilation_error/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: missing_function_body 2 | import 'package:mason/mason.dart';void run(HookContext context) 3 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/compilation_error/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: compilation_error_hooks 2 | 3 | environment: 4 | sdk: ">=2.12.0 <3.0.0" 5 | 6 | dependencies: 7 | mason: 8 | git: 9 | url: https://github.com/felangel/mason 10 | path: packages/mason 11 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/custom_registry/brick.yaml: -------------------------------------------------------------------------------- 1 | name: custom_registry 2 | description: A Simple Template that should be published to a custom registry 3 | version: 0.1.0+1 4 | publish_to: https://custom.brickhub.dev 5 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/enum_no_choices/__brick__/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason_cli/test/bricks/enum_no_choices/__brick__/.gitkeep -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/enum_no_choices/brick.yaml: -------------------------------------------------------------------------------- 1 | name: enum_no_choices 2 | description: A new brick created with the Mason CLI. 3 | 4 | version: 0.1.0+1 5 | 6 | environment: 7 | mason: ^0.1.1 8 | 9 | vars: 10 | color: 11 | type: enum 12 | description: Your favorite color 13 | prompt: What is your favorite color? 14 | values: 15 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/invalid_registry/brick.yaml: -------------------------------------------------------------------------------- 1 | name: invalid_registry 2 | description: A Simple Template that should be published to an invalid custom registry 3 | version: 0.1.0+1 4 | publish_to: invalid registry 5 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bricks/no_registry/brick.yaml: -------------------------------------------------------------------------------- 1 | name: no_registry 2 | description: A Simple Template that cannot be published 3 | version: 0.1.0+1 4 | publish_to: none 5 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bundles/bundles.dart: -------------------------------------------------------------------------------- 1 | export 'greeting_bundle.dart'; 2 | export 'hooks_bundle.dart'; 3 | export 'legacy_greeting_bundle.dart'; 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bundles/greeting.bundle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason_cli/test/bundles/greeting.bundle -------------------------------------------------------------------------------- /packages/mason_cli/test/bundles/greeting_bundle.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | // ignore_for_file: type=lint, implicit_dynamic_list_literal, implicit_dynamic_map_literal, inference_failure_on_collection_literal 3 | import 'package:mason/mason.dart'; 4 | 5 | final greetingBundle = MasonBundle.fromJson({ 6 | "files": [ 7 | {"path": "GREETINGS.md", "data": "SGkge3tuYW1lfX0h", "type": "text"} 8 | ], 9 | "hooks": [], 10 | "name": "greeting", 11 | "description": "A Simple Greeting Template", 12 | "version": "0.1.0+1", 13 | "environment": {"mason": "any"}, 14 | "vars": { 15 | "name": { 16 | "type": "string", 17 | "description": "Your name", 18 | "default": "Dash", 19 | "prompt": "What is your name?" 20 | } 21 | } 22 | }); 23 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bundles/hooks_bundle.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | // ignore_for_file: type=lint, implicit_dynamic_list_literal, implicit_dynamic_map_literal, inference_failure_on_collection_literal 3 | 4 | import 'package:mason/mason.dart'; 5 | 6 | final hooksBundle = MasonBundle.fromJson({ 7 | "files": [ 8 | {"path": "hooks.md", "data": "SGkge3tuYW1lfX0h", "type": "text"} 9 | ], 10 | "hooks": [ 11 | { 12 | "path": "post_gen.dart", 13 | "data": 14 | "aW1wb3J0ICdkYXJ0OmlvJztpbXBvcnQgJ3BhY2thZ2U6bWFzb24vbWFzb24uZGFydCc7dm9pZCBydW4oSG9va0NvbnRleHQgY29udGV4dCl7ZmluYWwgZmlsZT1GaWxlKCcucG9zdF9nZW4udHh0Jyk7ZmlsZS53cml0ZUFzU3RyaW5nU3luYygncG9zdF9nZW46ICR7Y29udGV4dC52YXJzWyduYW1lJ119Jyk7fQ==", 15 | "type": "text" 16 | }, 17 | { 18 | "path": "pre_gen.dart", 19 | "data": 20 | "aW1wb3J0ICdkYXJ0OmlvJztpbXBvcnQgJ3BhY2thZ2U6bWFzb24vbWFzb24uZGFydCc7dm9pZCBydW4oSG9va0NvbnRleHQgY29udGV4dCl7ZmluYWwgZmlsZT1GaWxlKCcucHJlX2dlbi50eHQnKTtmaWxlLndyaXRlQXNTdHJpbmdTeW5jKCdwcmVfZ2VuOiAke2NvbnRleHQudmFyc1snbmFtZSddfScpO30=", 21 | "type": "text" 22 | }, 23 | { 24 | "path": "pubspec.yaml", 25 | "data": 26 | "bmFtZTogaG9va3NfaG9va3MKCmVudmlyb25tZW50OgogIHNkazogIj49Mi4xMi4wIDwzLjAuMCIKCmRlcGVuZGVuY2llczoKICBtYXNvbjoKICAgIGdpdDoKICAgICAgdXJsOiBodHRwczovL2dpdGh1Yi5jb20vZmVsYW5nZWwvbWFzb24KICAgICAgcGF0aDogcGFja2FnZXMvbWFzb24K", 27 | "type": "text" 28 | } 29 | ], 30 | "name": "hooks", 31 | "description": "A Hooks Example Template", 32 | "version": "0.1.0+1", 33 | "environment": {"mason": "any"}, 34 | "vars": { 35 | "name": { 36 | "type": "string", 37 | "description": "Your name", 38 | "default": "Dash", 39 | "prompt": "What is your name?" 40 | } 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /packages/mason_cli/test/bundles/legacy_greeting_bundle.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | // ignore_for_file: type=lint, implicit_dynamic_list_literal, implicit_dynamic_map_literal, inference_failure_on_collection_literal 3 | 4 | import 'package:mason/mason.dart'; 5 | 6 | final legacyGreetingBundle = MasonBundle.fromJson({ 7 | "files": [ 8 | {"path": "GREETINGS.md", "data": "SGkge3tuYW1lfX0h", "type": "text"} 9 | ], 10 | "name": "greeting", 11 | "description": "A Simple Greeting Template", 12 | "version": "1.0.0", 13 | "vars": ['name'] 14 | }); 15 | -------------------------------------------------------------------------------- /packages/mason_cli/test/ensure_build_test.dart: -------------------------------------------------------------------------------- 1 | @Tags(['pull-request-only']) 2 | library; 3 | 4 | import 'package:build_verify/build_verify.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | test( 9 | 'ensure_build', 10 | () => expectBuildClean(packageRelativeDirectory: 'packages/mason_cli'), 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/add/greeting/GREETINGS.md: -------------------------------------------------------------------------------- 1 | Hi Dash! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/add/widget/cat.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Cat extends StatelessWidget { 4 | const Cat({super.key}); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return const SizedBox(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/init/mason.yaml: -------------------------------------------------------------------------------- 1 | # Register bricks which can be consumed via the Mason CLI. 2 | # Run "mason get" to install all registered bricks. 3 | # To learn more, visit https://docs.brickhub.dev. 4 | bricks: 5 | # Bricks can be imported via version constraint from a registry. 6 | # Uncomment the following line to import the "hello" brick from BrickHub. 7 | # hello: 0.1.0+2 8 | # Bricks can also be imported via remote git url. 9 | # Uncomment the following lines to import the "widget" brick from git. 10 | # widget: 11 | # git: 12 | # url: https://github.com/felangel/mason.git 13 | # path: bricks/widget 14 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/install/greeting/GREETINGS.md: -------------------------------------------------------------------------------- 1 | Hi Dash! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/install/widget/cat.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Cat extends StatelessWidget { 4 | const Cat({super.key}); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | child: child, 10 | ); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/app_icon/c823e53b3a1a7b0d36a9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felangel/mason/3643c466f6ee117fa9a766f3bdf5d36eefbd9389/packages/mason_cli/test/fixtures/make/app_icon/c823e53b3a1a7b0d36a9.png -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/bio/ABOUT.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Hello, my name is Dash! I am 42 years old and I am not a developer. -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/documentation/.gitignore: -------------------------------------------------------------------------------- 1 | # Temporary Files 2 | .tmp/ -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/documentation/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.0.0 2 | 3 | - initial release 🎉 -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/documentation/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2020 test-author 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without restriction, 7 | including without limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of the Software, 9 | and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 | USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/documentation/README.md: -------------------------------------------------------------------------------- 1 | # test-name 💙 2 | 3 | test-description 4 | 5 | ## Usage 🚀 6 | 7 | ```sh 8 | # Test Name 9 | ``` 10 | 11 | ``` 12 | ├── foo 13 | │ ├── bar 14 | │ │ ├── baz 15 | │ │ └── baz 16 | ``` 17 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/favorite_color/color.md: -------------------------------------------------------------------------------- 1 | Your favorite color is blue! 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/favorite_languages/languages.md: -------------------------------------------------------------------------------- 1 | Your favorite languages are: 2 | - dart 3 | - rust 4 | - c++ 5 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/flavors/README.md: -------------------------------------------------------------------------------- 1 | This project supports the following flavors: 2 | 3 | - development 4 | - production -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/flavors/main_development.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Running in development mode...'); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/flavors/main_production.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Running in production mode...'); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/greeting/GREETINGS.md: -------------------------------------------------------------------------------- 1 | Hi test-name! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/hello_world/HELLO.md: -------------------------------------------------------------------------------- 1 | # 🧱 dash 2 | 3 | Hello dash! 4 | 5 | _made with 💖 by mason_ -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/hooks/basic/.post_gen.txt: -------------------------------------------------------------------------------- 1 | post_gen: dash -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/hooks/basic/.pre_gen.txt: -------------------------------------------------------------------------------- 1 | pre_gen: dash -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/hooks/basic/hooks.md: -------------------------------------------------------------------------------- 1 | Hi dash! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/hooks/no_hooks/hooks.md: -------------------------------------------------------------------------------- 1 | Hi dash! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/mason.yaml: -------------------------------------------------------------------------------- 1 | bricks: 2 | app_icon: 3 | path: ../../../../../bricks/app_icon 4 | bio: 5 | path: ../../../../../bricks/bio 6 | documentation: 7 | path: ../../../../../bricks/documentation 8 | favorite_color: 9 | path: ../../../../../bricks/favorite_color 10 | flavors: 11 | path: ../../../../../bricks/flavors 12 | hello_world: 13 | path: ../../../../../bricks/hello_world 14 | hooks: 15 | path: ../../../../../bricks/hooks 16 | greeting: 17 | path: ../../../../../bricks/greeting 18 | legacy: 19 | path: ../../../../../bricks/legacy 20 | plugin: 21 | path: ../../../../../bricks/plugin 22 | random_color: 23 | path: ../../../../../bricks/random_color 24 | simple: 25 | path: ../../../../../bricks/simple 26 | todos: 27 | path: ../../../../../bricks/todos 28 | widget: 29 | path: ../../../../../bricks/widget 30 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/output_dir/dir/GREETINGS.md: -------------------------------------------------------------------------------- 1 | Hi test-name! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android/README.md: -------------------------------------------------------------------------------- 1 | # Plugin 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android/android/README.md: -------------------------------------------------------------------------------- 1 | # Android Plugin 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Empty build.gradle -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android/example/android.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Android'); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android/tests/android_tests.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | test('Android Test', () {}); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android_ios/Podfile: -------------------------------------------------------------------------------- 1 | # Empty Podfile -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android_ios/README.md: -------------------------------------------------------------------------------- 1 | # Plugin 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android_ios/android/README.md: -------------------------------------------------------------------------------- 1 | # Android Plugin 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android_ios/build.gradle: -------------------------------------------------------------------------------- 1 | // Empty build.gradle -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android_ios/example/android.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Android'); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android_ios/example/ios.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Android'); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android_ios/ios/README.md: -------------------------------------------------------------------------------- 1 | # iOS Plugin 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android_ios/tests/android_tests.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | test('Android Test', () {}); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/android_ios/tests/ios_tests.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | test('iOS Test', () {}); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/empty/README.md: -------------------------------------------------------------------------------- 1 | # Plugin 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Empty Podfile -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/ios/README.md: -------------------------------------------------------------------------------- 1 | # Plugin 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/ios/example/ios.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | print('Android'); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/ios/ios/README.md: -------------------------------------------------------------------------------- 1 | # iOS Plugin 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/plugin/ios/tests/ios_tests.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | test('iOS Test', () {}); 3 | } 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/simple/HELLO.md: -------------------------------------------------------------------------------- 1 | Hello World! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos.md: -------------------------------------------------------------------------------- 1 | # TODOS 2 | 3 | - [X] Eat 4 | - [X] Code 5 | - [ ] Sleep 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos.json: -------------------------------------------------------------------------------- 1 | { 2 | "todos": [ 3 | { "todo": "Eat", "done": true }, 4 | { "todo": "Code", "done": true }, 5 | { "todo": "Sleep", "done": false } 6 | ], 7 | "developers": [{ "name": "Alex" }, { "name": "Sam" }, { "name": "Jen" }] 8 | } 9 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos.md: -------------------------------------------------------------------------------- 1 | # TODOS 2 | 3 | - [X] Eat 4 | - [X] Code 5 | - [ ] Sleep 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/Code/developers/Alex/info.md: -------------------------------------------------------------------------------- 1 | # Alex 2 | 3 | ## TODO: Code 4 | 5 | **DONE** 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/Code/developers/Jen/info.md: -------------------------------------------------------------------------------- 1 | # Jen 2 | 3 | ## TODO: Code 4 | 5 | **DONE** 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/Code/developers/Sam/info.md: -------------------------------------------------------------------------------- 1 | # Sam 2 | 3 | ## TODO: Code 4 | 5 | **DONE** 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/Eat/developers/Alex/info.md: -------------------------------------------------------------------------------- 1 | # Alex 2 | 3 | ## TODO: Eat 4 | 5 | **DONE** 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/Eat/developers/Jen/info.md: -------------------------------------------------------------------------------- 1 | # Jen 2 | 3 | ## TODO: Eat 4 | 5 | **DONE** 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/Eat/developers/Sam/info.md: -------------------------------------------------------------------------------- 1 | # Sam 2 | 3 | ## TODO: Eat 4 | 5 | **DONE** 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/Sleep/developers/Alex/info.md: -------------------------------------------------------------------------------- 1 | # Alex 2 | 3 | ## TODO: Sleep 4 | 5 | **TODO** 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/Sleep/developers/Jen/info.md: -------------------------------------------------------------------------------- 1 | # Jen 2 | 3 | ## TODO: Sleep 4 | 5 | **TODO** 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/Sleep/developers/Sam/info.md: -------------------------------------------------------------------------------- 1 | # Sam 2 | 3 | ## TODO: Sleep 4 | 5 | **TODO** 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/todo_CODE_todo.md: -------------------------------------------------------------------------------- 1 | # TODO Code 2 | 3 | DONE! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/todo_EAT_todo.md: -------------------------------------------------------------------------------- 1 | # TODO Eat 2 | 3 | DONE! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/todos/todos/todo_SLEEP_todo.md: -------------------------------------------------------------------------------- 1 | # TODO Sleep 2 | 3 | TODO -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/make/widget/my_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class MyWidget extends StatelessWidget { 4 | const MyWidget({super.key}); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return const SizedBox(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/custom/bricks/hello_world/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.1.0+1 2 | 3 | - TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/custom/bricks/hello_world/LICENSE: -------------------------------------------------------------------------------- 1 | TODO: Add your license here. 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/custom/bricks/hello_world/README.md: -------------------------------------------------------------------------------- 1 | # hello_world 2 | 3 | [![Powered by Mason](https://img.shields.io/endpoint?url=https%3A%2F%2Ftinyurl.com%2Fmason-badge)](https://github.com/felangel/mason) 4 | 5 | A new brick created with the Mason CLI. 6 | 7 | _Generated by [mason][1] 🧱_ 8 | 9 | ## Getting Started 🚀 10 | 11 | This is a starting point for a new brick. 12 | A few resources to get you started if this is your first brick template: 13 | 14 | - [Official Mason Documentation][2] 15 | - [Code generation with Mason Blog][3] 16 | - [Very Good Livestream: Felix Angelov Demos Mason][4] 17 | - [Flutter Package of the Week: Mason][5] 18 | - [Observable Flutter: Building a Mason brick][6] 19 | - [Meet Mason: Flutter Vikings 2022][7] 20 | 21 | [1]: https://github.com/felangel/mason 22 | [2]: https://docs.brickhub.dev 23 | [3]: https://verygood.ventures/blog/code-generation-with-mason 24 | [4]: https://youtu.be/G4PTjA6tpTU 25 | [5]: https://youtu.be/qjA0JFiPMnQ 26 | [6]: https://youtu.be/o8B1EfcUisw 27 | [7]: https://youtu.be/LXhgiF5HiQg 28 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/custom/bricks/hello_world/__brick__/HELLO.md: -------------------------------------------------------------------------------- 1 | Hello {{name}}! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/custom/bricks/hello_world/brick.yaml: -------------------------------------------------------------------------------- 1 | name: hello_world 2 | description: A new brick created with the Mason CLI. 3 | 4 | # The following defines the brick repository url. 5 | # Uncomment and update the following line before publishing the brick. 6 | # repository: https://github.com/my_org/my_repo 7 | 8 | # The following defines the version and build number for your brick. 9 | # A version number is three numbers separated by dots, like 1.2.34 10 | # followed by an optional build number (separated by a +). 11 | version: 0.1.0+1 12 | 13 | # The following defines the environment for the current brick. 14 | # It includes the version of mason that the brick requires. 15 | environment: 16 | mason: ^0.1.1 17 | 18 | # Variables specify dynamic values that your brick depends on. 19 | # Zero or more variables can be specified for a given brick. 20 | # Each variable has: 21 | # * a type (string, number, boolean, enum, array, or list) 22 | # * an optional short description 23 | # * an optional default value 24 | # * an optional list of default values (array only) 25 | # * an optional prompt phrase used when asking for the variable 26 | # * a list of values (enums only) 27 | # * an optional separator (list only) 28 | vars: 29 | name: 30 | type: string 31 | description: Your name 32 | default: Dash 33 | prompt: What is your name? 34 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/hooks/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.1.0+1 2 | 3 | - TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/hooks/LICENSE: -------------------------------------------------------------------------------- 1 | TODO: Add your license here. 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/hooks/README.md: -------------------------------------------------------------------------------- 1 | # hooks 2 | 3 | [![Powered by Mason](https://img.shields.io/endpoint?url=https%3A%2F%2Ftinyurl.com%2Fmason-badge)](https://github.com/felangel/mason) 4 | 5 | A new brick created with the Mason CLI. 6 | 7 | _Generated by [mason][1] 🧱_ 8 | 9 | ## Getting Started 🚀 10 | 11 | This is a starting point for a new brick. 12 | A few resources to get you started if this is your first brick template: 13 | 14 | - [Official Mason Documentation][2] 15 | - [Code generation with Mason Blog][3] 16 | - [Very Good Livestream: Felix Angelov Demos Mason][4] 17 | - [Flutter Package of the Week: Mason][5] 18 | - [Observable Flutter: Building a Mason brick][6] 19 | - [Meet Mason: Flutter Vikings 2022][7] 20 | 21 | [1]: https://github.com/felangel/mason 22 | [2]: https://docs.brickhub.dev 23 | [3]: https://verygood.ventures/blog/code-generation-with-mason 24 | [4]: https://youtu.be/G4PTjA6tpTU 25 | [5]: https://youtu.be/qjA0JFiPMnQ 26 | [6]: https://youtu.be/o8B1EfcUisw 27 | [7]: https://youtu.be/LXhgiF5HiQg 28 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/hooks/__brick__/HELLO.md: -------------------------------------------------------------------------------- 1 | Hello {{name}}! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/hooks/brick.yaml: -------------------------------------------------------------------------------- 1 | name: hooks 2 | description: A new brick created with the Mason CLI. 3 | 4 | # The following defines the brick repository url. 5 | # Uncomment and update the following line before publishing the brick. 6 | # repository: https://github.com/my_org/my_repo 7 | 8 | # The following defines the version and build number for your brick. 9 | # A version number is three numbers separated by dots, like 1.2.34 10 | # followed by an optional build number (separated by a +). 11 | version: 0.1.0+1 12 | 13 | # The following defines the environment for the current brick. 14 | # It includes the version of mason that the brick requires. 15 | environment: 16 | mason: ^0.1.1 17 | 18 | # Variables specify dynamic values that your brick depends on. 19 | # Zero or more variables can be specified for a given brick. 20 | # Each variable has: 21 | # * a type (string, number, boolean, enum, array, or list) 22 | # * an optional short description 23 | # * an optional default value 24 | # * an optional list of default values (array only) 25 | # * an optional prompt phrase used when asking for the variable 26 | # * a list of values (enums only) 27 | # * an optional separator (list only) 28 | vars: 29 | name: 30 | type: string 31 | description: Your name 32 | default: Dash 33 | prompt: What is your name? 34 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/hooks/hooks/.gitignore: -------------------------------------------------------------------------------- 1 | .dart_tool 2 | .packages 3 | pubspec.lock 4 | build 5 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/hooks/hooks/post_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | 3 | void run(HookContext context) { 4 | // TODO: add post-generation logic. 5 | } 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/hooks/hooks/pre_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason/mason.dart'; 2 | 3 | void run(HookContext context) { 4 | // TODO: add pre-generation logic. 5 | } 6 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/hooks/hooks/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: hooks_hooks 2 | 3 | environment: 4 | sdk: ^3.5.4 5 | 6 | dependencies: 7 | mason: ^0.1.1 8 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/simple/hello_world/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.1.0+1 2 | 3 | - TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/simple/hello_world/LICENSE: -------------------------------------------------------------------------------- 1 | TODO: Add your license here. 2 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/simple/hello_world/README.md: -------------------------------------------------------------------------------- 1 | # hello_world 2 | 3 | [![Powered by Mason](https://img.shields.io/endpoint?url=https%3A%2F%2Ftinyurl.com%2Fmason-badge)](https://github.com/felangel/mason) 4 | 5 | A new brick created with the Mason CLI. 6 | 7 | _Generated by [mason][1] 🧱_ 8 | 9 | ## Getting Started 🚀 10 | 11 | This is a starting point for a new brick. 12 | A few resources to get you started if this is your first brick template: 13 | 14 | - [Official Mason Documentation][2] 15 | - [Code generation with Mason Blog][3] 16 | - [Very Good Livestream: Felix Angelov Demos Mason][4] 17 | - [Flutter Package of the Week: Mason][5] 18 | - [Observable Flutter: Building a Mason brick][6] 19 | - [Meet Mason: Flutter Vikings 2022][7] 20 | 21 | [1]: https://github.com/felangel/mason 22 | [2]: https://docs.brickhub.dev 23 | [3]: https://verygood.ventures/blog/code-generation-with-mason 24 | [4]: https://youtu.be/G4PTjA6tpTU 25 | [5]: https://youtu.be/qjA0JFiPMnQ 26 | [6]: https://youtu.be/o8B1EfcUisw 27 | [7]: https://youtu.be/LXhgiF5HiQg 28 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/simple/hello_world/__brick__/HELLO.md: -------------------------------------------------------------------------------- 1 | Hello {{name}}! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/new/simple/hello_world/brick.yaml: -------------------------------------------------------------------------------- 1 | name: hello_world 2 | description: A new brick created with the Mason CLI. 3 | 4 | # The following defines the brick repository url. 5 | # Uncomment and update the following line before publishing the brick. 6 | # repository: https://github.com/my_org/my_repo 7 | 8 | # The following defines the version and build number for your brick. 9 | # A version number is three numbers separated by dots, like 1.2.34 10 | # followed by an optional build number (separated by a +). 11 | version: 0.1.0+1 12 | 13 | # The following defines the environment for the current brick. 14 | # It includes the version of mason that the brick requires. 15 | environment: 16 | mason: ^0.1.1 17 | 18 | # Variables specify dynamic values that your brick depends on. 19 | # Zero or more variables can be specified for a given brick. 20 | # Each variable has: 21 | # * a type (string, number, boolean, enum, array, or list) 22 | # * an optional short description 23 | # * an optional default value 24 | # * an optional list of default values (array only) 25 | # * an optional prompt phrase used when asking for the variable 26 | # * a list of values (enums only) 27 | # * an optional separator (list only) 28 | vars: 29 | name: 30 | type: string 31 | description: Your name 32 | default: Dash 33 | prompt: What is your name? 34 | -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/unbundle/__brick__/GREETINGS.md: -------------------------------------------------------------------------------- 1 | Hi {{name}}! -------------------------------------------------------------------------------- /packages/mason_cli/test/fixtures/unbundle/brick.yaml: -------------------------------------------------------------------------------- 1 | name: greeting 2 | description: A Simple Greeting Template 3 | version: 0.1.0+1 4 | environment: 5 | mason: any 6 | vars: 7 | name: 8 | type: string 9 | description: Your name 10 | default: Dash 11 | prompt: "What is your name?" -------------------------------------------------------------------------------- /packages/mason_cli/test/helpers/directories_deep_equal.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:collection/collection.dart'; 4 | import 'package:path/path.dart' as path; 5 | 6 | const _equality = DeepCollectionEquality(); 7 | 8 | bool directoriesDeepEqual( 9 | Directory? a, 10 | Directory? b, { 11 | List ignore = const [], 12 | }) { 13 | if (identical(a, b)) return true; 14 | if (a == null && b == null) return true; 15 | if (a == null || b == null) return false; 16 | 17 | final dirAContents = a.listSync(recursive: true).whereType(); 18 | final dirBContents = b.listSync(recursive: true).whereType(); 19 | 20 | if (dirAContents.length != dirBContents.length) return false; 21 | 22 | for (var i = 0; i < dirAContents.length; i++) { 23 | final fileEntityA = dirAContents.elementAt(i); 24 | final fileEntityB = dirBContents.elementAt(i); 25 | 26 | final fileA = File(fileEntityA.path); 27 | final fileB = File(fileEntityB.path); 28 | 29 | if (path.basename(fileA.path) != path.basename(fileB.path)) return false; 30 | if (ignore.contains(path.basename(fileA.path))) continue; 31 | try { 32 | final normalizedA = fileA 33 | .readAsStringSync() 34 | .replaceAll('\r', '') 35 | .replaceAll('\n', '') 36 | .replaceAll(r'\', '/'); 37 | final normalizedB = fileB 38 | .readAsStringSync() 39 | .replaceAll('\r', '') 40 | .replaceAll('\n', '') 41 | .replaceAll(r'\', '/'); 42 | if (!_equality.equals(normalizedA, normalizedB)) return false; 43 | } catch (_) { 44 | if (!_equality.equals(fileA.readAsBytesSync(), fileB.readAsBytesSync())) { 45 | return false; 46 | } 47 | } 48 | } 49 | 50 | return true; 51 | } 52 | -------------------------------------------------------------------------------- /packages/mason_cli/test/helpers/helpers.dart: -------------------------------------------------------------------------------- 1 | export 'directories_deep_equal.dart'; 2 | export 'override_print.dart'; 3 | export 'set_up_testing_environment.dart'; 4 | -------------------------------------------------------------------------------- /packages/mason_cli/test/helpers/override_print.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | List printLogs = []; 4 | 5 | void Function() overridePrint(void Function() fn) { 6 | return () { 7 | final spec = ZoneSpecification( 8 | print: (_, __, ___, String msg) { 9 | printLogs.add(msg); 10 | }, 11 | ); 12 | return Zone.current.fork(specification: spec).run(fn); 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /packages/mason_cli/test/helpers/set_up_testing_environment.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:path/path.dart' as path; 4 | 5 | String testFixturesPath(Directory cwd, {String suffix = ''}) { 6 | return path.join(cwd.path, 'test', 'fixtures', suffix); 7 | } 8 | 9 | void setUpTestingEnvironment(Directory cwd, {String suffix = ''}) { 10 | try { 11 | final testDir = Directory(testFixturesPath(cwd, suffix: suffix)); 12 | if (testDir.existsSync()) testDir.deleteSync(recursive: true); 13 | testDir.createSync(recursive: true); 14 | Directory.current = testDir.path; 15 | File( 16 | path.join(Directory.current.path, '.mason', 'bricks.json'), 17 | ).deleteSync(); 18 | } catch (_) {} 19 | } 20 | -------------------------------------------------------------------------------- /packages/mason_logger/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | 5 | # Remove the following pattern if you wish to check in your lock file 6 | pubspec.lock 7 | 8 | # Conventional directory for build outputs 9 | build/ 10 | 11 | # Directory created by dartdoc 12 | doc/api/ 13 | 14 | # Temporary Files 15 | .tmp/ 16 | 17 | # Local Mason Files 18 | .mason/ 19 | 20 | # Test Related Files 21 | coverage/ 22 | .test_coverage.dart -------------------------------------------------------------------------------- /packages/mason_logger/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2024 Felix Angelov 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without restriction, 7 | including without limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of the Software, 9 | and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 | USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/mason_logger/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: ../../analysis_options.yaml 2 | analyzer: 3 | errors: 4 | todo: ignore -------------------------------------------------------------------------------- /packages/mason_logger/coverage_badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | coverage 16 | coverage 17 | 100% 18 | 100% 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/mason_logger/lib/mason_logger.dart: -------------------------------------------------------------------------------- 1 | /// A reusable Dart logger used by the Mason CLI. 2 | /// 3 | /// Get started at [https://github.com/felangel/mason](https://github.com/felangel/mason) 🧱 4 | library mason_logger; 5 | 6 | export 'src/ansi.dart'; 7 | export 'src/io.dart' hide ControlCharacter, KeyStroke, readKey; 8 | export 'src/level.dart'; 9 | export 'src/link.dart'; 10 | export 'src/mason_logger.dart' 11 | show 12 | LogStyle, 13 | LogTheme, 14 | Logger, 15 | Progress, 16 | ProgressAnimation, 17 | ProgressOptions; 18 | -------------------------------------------------------------------------------- /packages/mason_logger/lib/src/ansi.dart: -------------------------------------------------------------------------------- 1 | export 'package:io/ansi.dart' 2 | show 3 | AnsiCode, 4 | AnsiCodeType, 5 | ansiOutputEnabled, 6 | backgroundBlack, 7 | backgroundBlue, 8 | backgroundColors, 9 | backgroundCyan, 10 | backgroundDarkGray, 11 | backgroundDefault, 12 | backgroundGreen, 13 | backgroundLightBlue, 14 | backgroundLightCyan, 15 | backgroundLightGray, 16 | backgroundLightGreen, 17 | backgroundLightMagenta, 18 | backgroundLightRed, 19 | backgroundLightYellow, 20 | backgroundMagenta, 21 | backgroundRed, 22 | backgroundWhite, 23 | backgroundYellow, 24 | black, 25 | blue, 26 | cyan, 27 | darkGray, 28 | defaultForeground, 29 | foregroundColors, 30 | green, 31 | lightBlue, 32 | lightCyan, 33 | lightGray, 34 | lightGreen, 35 | lightMagenta, 36 | lightRed, 37 | lightYellow, 38 | magenta, 39 | overrideAnsiOutput, 40 | red, 41 | resetAll, 42 | resetBlink, 43 | resetBold, 44 | resetDim, 45 | resetItalic, 46 | resetReverse, 47 | resetUnderlined, 48 | styleBlink, 49 | styleBold, 50 | styleDim, 51 | styleItalic, 52 | styleReverse, 53 | styleUnderlined, 54 | styles, 55 | white, 56 | yellow; 57 | -------------------------------------------------------------------------------- /packages/mason_logger/lib/src/ffi/terminal.dart: -------------------------------------------------------------------------------- 1 | // coverage:ignore-file 2 | 3 | import 'dart:io'; 4 | 5 | import 'package:mason_logger/src/ffi/unix_terminal.dart'; 6 | import 'package:mason_logger/src/ffi/windows_terminal.dart'; 7 | 8 | /// {@template terminal} 9 | /// Interface for the underlying native terminal. 10 | /// {@endtemplate} 11 | abstract class Terminal { 12 | /// {@macro terminal} 13 | factory Terminal() => Platform.isWindows ? WindowsTerminal() : UnixTerminal(); 14 | 15 | /// Enables raw mode which allows us to process each keypress as it comes in. 16 | /// https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html 17 | void enableRawMode(); 18 | 19 | /// Disables raw mode and restores the terminal’s original attributes. 20 | void disableRawMode(); 21 | } 22 | -------------------------------------------------------------------------------- /packages/mason_logger/lib/src/ffi/windows_terminal.dart: -------------------------------------------------------------------------------- 1 | // coverage:ignore-file 2 | // ignore_for_file: public_member_api_docs 3 | 4 | import 'package:mason_logger/src/ffi/terminal.dart'; 5 | import 'package:win32/win32.dart'; 6 | 7 | class WindowsTerminal implements Terminal { 8 | WindowsTerminal() { 9 | outputHandle = GetStdHandle(STD_OUTPUT_HANDLE); 10 | inputHandle = GetStdHandle(STD_INPUT_HANDLE); 11 | } 12 | 13 | late final int inputHandle; 14 | late final int outputHandle; 15 | 16 | @override 17 | void enableRawMode() { 18 | const dwMode = (~ENABLE_ECHO_INPUT) & 19 | (~ENABLE_PROCESSED_INPUT) & 20 | (~ENABLE_LINE_INPUT) & 21 | (~ENABLE_WINDOW_INPUT); 22 | SetConsoleMode(inputHandle, dwMode); 23 | } 24 | 25 | @override 26 | void disableRawMode() { 27 | const dwMode = ENABLE_ECHO_INPUT | 28 | ENABLE_EXTENDED_FLAGS | 29 | ENABLE_INSERT_MODE | 30 | ENABLE_LINE_INPUT | 31 | ENABLE_MOUSE_INPUT | 32 | ENABLE_PROCESSED_INPUT | 33 | ENABLE_QUICK_EDIT_MODE | 34 | ENABLE_VIRTUAL_TERMINAL_INPUT; 35 | SetConsoleMode(inputHandle, dwMode); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/mason_logger/lib/src/level.dart: -------------------------------------------------------------------------------- 1 | /// Indicates the desired logging level. 2 | enum Level { 3 | /// The most verbose log level -- everything is logged. 4 | verbose, 5 | 6 | /// Used for debug info. 7 | debug, 8 | 9 | /// Default log level used for standard logs. 10 | info, 11 | 12 | /// Used to indicate a potential problem. 13 | warning, 14 | 15 | /// Used to indicate a problem. 16 | error, 17 | 18 | /// Used to indicate an urgent/severe problem. 19 | critical, 20 | 21 | /// The least verbose level -- nothing is logged. 22 | quiet, 23 | } 24 | -------------------------------------------------------------------------------- /packages/mason_logger/lib/src/link.dart: -------------------------------------------------------------------------------- 1 | import 'package:io/ansi.dart'; 2 | 3 | /// Wraps [uri] with an escape sequence so it's recognized as a hyperlink. 4 | /// An optional message can be used in place of the [uri]. 5 | /// If no [message] is provided, the text content will be the full [uri]. 6 | /// 7 | /// ```dart 8 | /// final plainLink = link(uri: Uri.parse('https://dart.dev')); 9 | /// print(plainLink); // Equivalent to `[https://dart.dev](https://dart.dev)` in markdown 10 | /// 11 | /// final richLink = link(uri: Uri.parse('https://dart.dev'), message: 'The Dart Website'); 12 | /// print(richLink); // Equivalent to `[The Dart Website](https://dart.dev)` in markdown 13 | /// ``` 14 | String link({required Uri uri, String? message}) { 15 | if (!ansiOutputEnabled) { 16 | return message != null ? '[$message]($uri)' : uri.toString(); 17 | } 18 | 19 | const leading = '\x1B]8;;'; 20 | const trailing = '\x1B\\'; 21 | 22 | return '$leading$uri$trailing${message ?? uri}$leading$trailing'; 23 | } 24 | -------------------------------------------------------------------------------- /packages/mason_logger/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mason_logger 2 | description: A reusable Dart logger used by the Mason CLI (package:mason_cli). 3 | version: 0.3.3 4 | homepage: https://github.com/felangel/mason 5 | repository: https://github.com/felangel/mason 6 | issue_tracker: https://github.com/felangel/mason/issues 7 | documentation: https://github.com/felangel/mason/tree/master/packages/mason_logger#readme 8 | topics: [cli, logger, mason] 9 | funding: [https://github.com/sponsors/felangel] 10 | 11 | platforms: 12 | android: 13 | ios: 14 | linux: 15 | macos: 16 | web: 17 | windows: 18 | 19 | environment: 20 | sdk: ">=3.5.0 <4.0.0" 21 | 22 | dependencies: 23 | ffi: ^2.1.3 24 | io: ^1.0.4 25 | win32: ^5.11.0 26 | 27 | dev_dependencies: 28 | meta: ^1.15.0 29 | mocktail: ^1.0.4 30 | test: ^1.25.8 31 | -------------------------------------------------------------------------------- /packages/mason_logger/test/ci.dart: -------------------------------------------------------------------------------- 1 | import 'package:mason_logger/mason_logger.dart'; 2 | 3 | Future main() async { 4 | final logger = Logger(); 5 | final progress = logger.progress('Calculating'); 6 | await Future.delayed(const Duration(seconds: 1)); 7 | progress.update('This is taking longer than expected'); 8 | await Future.delayed(const Duration(seconds: 1)); 9 | progress.update('Almost done'); 10 | await Future.delayed(const Duration(seconds: 1)); 11 | progress.complete('Done'); 12 | } 13 | -------------------------------------------------------------------------------- /packages/mason_logger/test/fixtures/ci.txt: -------------------------------------------------------------------------------- 1 | ⠋ Calculating... ⠙ This is taking longer than expected... (1.0s) ⠹ Almost done... (2.0s) ✓ Done (3.0s) 2 | -------------------------------------------------------------------------------- /packages/mason_logger/test/src/link_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:mason_logger/mason_logger.dart'; 4 | import 'package:mocktail/mocktail.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | class _MockStdout extends Mock implements Stdout {} 8 | 9 | void main() { 10 | group('link', () { 11 | late Stdout stdout; 12 | late Stdout stderr; 13 | 14 | setUp(() { 15 | stdout = _MockStdout(); 16 | stderr = _MockStdout(); 17 | when(() => stdout.supportsAnsiEscapes).thenReturn(true); 18 | when(() => stderr.supportsAnsiEscapes).thenReturn(true); 19 | }); 20 | 21 | R runWithOverrides(R Function() body) { 22 | return IOOverrides.runZoned( 23 | body, 24 | stdout: () => stdout, 25 | stderr: () => stderr, 26 | ); 27 | } 28 | 29 | final uri = Uri.parse('https://github.com/felangel/mason/issues/'); 30 | const lead = '\x1B]8;;'; 31 | const trail = '\x1B\\'; 32 | 33 | test( 34 | 'builds output with correct encodings: ' r'\x1B]8;;' ' and ' r'\x1B\\', 35 | () { 36 | const message = 'message'; 37 | final output = runWithOverrides(() => link(message: message, uri: uri)); 38 | final matcher = stringContainsInOrder( 39 | [lead, '$uri', trail, message, lead, trail], 40 | ); 41 | 42 | expect(output, matcher); 43 | }, 44 | ); 45 | 46 | test('builds String with Uri when message is null: ', () { 47 | final output = runWithOverrides(() => link(uri: uri)); 48 | final matcher = stringContainsInOrder( 49 | [lead, '$uri', trail, '$uri', lead, trail], 50 | ); 51 | 52 | expect(output, matcher); 53 | }); 54 | 55 | test('builds output when ansi escapes are not supported', () { 56 | when(() => stdout.supportsAnsiEscapes).thenReturn(false); 57 | when(() => stderr.supportsAnsiEscapes).thenReturn(false); 58 | final output = runWithOverrides(() => link(uri: uri)); 59 | final matcher = stringContainsInOrder(['$uri']); 60 | expect(output, matcher); 61 | }); 62 | 63 | test('builds output with message when ansi escapes are not supported', () { 64 | when(() => stdout.supportsAnsiEscapes).thenReturn(false); 65 | when(() => stderr.supportsAnsiEscapes).thenReturn(false); 66 | const message = 'message'; 67 | final output = runWithOverrides(() => link(uri: uri, message: message)); 68 | expect(output, equals('[$message]($uri)')); 69 | }); 70 | }); 71 | } 72 | -------------------------------------------------------------------------------- /tool/verify_pub_score.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Runs `pana . --no-warning` and verifies that the package score 3 | # is greater or equal to the desired score. By default the desired score is 4 | # a perfect score but it can be overridden by passing the desired score as an argument. 5 | # 6 | # Ensure the package has a score of at least a 100 7 | # `./verify_pub_score.sh 100` 8 | # 9 | # Ensure the package has a perfect score 10 | # `./verify_pub_score.sh` 11 | 12 | PANA=$(pana . --no-warning); PANA_SCORE=$(echo $PANA | sed -n "s/.*Points: \([0-9]*\)\/\([0-9]*\)./\1\/\2/p") 13 | echo "score: $PANA_SCORE" 14 | IFS='/'; read -a SCORE_ARR <<< "$PANA_SCORE"; SCORE=SCORE_ARR[0]; TOTAL=SCORE_ARR[1] 15 | if [ -z "$1" ]; then MINIMUM_SCORE=TOTAL; else MINIMUM_SCORE=$1; fi 16 | if (( $SCORE < $MINIMUM_SCORE )); then echo "minimum score $MINIMUM_SCORE was not met!"; exit 1; fi --------------------------------------------------------------------------------