From 3be0f304bc85a0f45b49627b9061436bdf388f85 Mon Sep 17 00:00:00 2001 From: hyiso Date: Sat, 14 Jan 2023 14:07:56 +0800 Subject: [PATCH 1/2] feat: Add scripts support and merge hooks to scripts BREAKING CHANGE: `hooks` now is merged into `scripts` --- packages/flutterw/bin/flutterw.dart | 2 +- packages/flutterw/example/pubspec.yaml | 4 +- packages/flutterw/lib/flutterw.dart | 1 - packages/flutterw/lib/src/config.dart | 28 ++------ packages/flutterw/lib/src/hook.dart | 70 ++++++++++---------- packages/flutterw/lib/src/runner.dart | 16 ++--- packages/flutterw/pubspec.yaml | 5 +- packages/flutterw/test/flutterw_test.dart | 2 +- packages/flutterw_clean/example/pubspec.yaml | 2 +- packages/flutterw_hook/lib/src/commands.dart | 18 ++--- packages/flutterw_hook/lib/src/config.dart | 52 ++++----------- packages/flutterw_hook/pubspec.yaml | 1 + packages/flutterw_hook/test/config_test.dart | 18 ++--- 13 files changed, 89 insertions(+), 130 deletions(-) diff --git a/packages/flutterw/bin/flutterw.dart b/packages/flutterw/bin/flutterw.dart index 5cb2cdd..4659833 100644 --- a/packages/flutterw/bin/flutterw.dart +++ b/packages/flutterw/bin/flutterw.dart @@ -7,5 +7,5 @@ Future main(List args) async { final config = file.existsSync() ? FlutterwConfig.fromFile(file) : FlutterwConfig.empty(); - await FlutterwRunner(config: config).run(args); + await FlutterwRunner(scripts: config.scripts).run(args); } diff --git a/packages/flutterw/example/pubspec.yaml b/packages/flutterw/example/pubspec.yaml index 8ea28a1..343e7ee 100644 --- a/packages/flutterw/example/pubspec.yaml +++ b/packages/flutterw/example/pubspec.yaml @@ -6,11 +6,11 @@ homepage: environment: sdk: '>=2.12.0 <3.0.0' -hooks: +scripts: pre:clean: - echo 'task 1' - echo 'task 2' - clean: flutterw_clean + clean: flutter pub run flutterw_clean post:clean: - echo 'task 3' - echo 'task 4' diff --git a/packages/flutterw/lib/flutterw.dart b/packages/flutterw/lib/flutterw.dart index 4a35684..37d65d7 100644 --- a/packages/flutterw/lib/flutterw.dart +++ b/packages/flutterw/lib/flutterw.dart @@ -1,3 +1,2 @@ export 'src/config.dart'; -export 'src/hook.dart'; export 'src/runner.dart'; diff --git a/packages/flutterw/lib/src/config.dart b/packages/flutterw/lib/src/config.dart index ba7df5e..d4f60c7 100644 --- a/packages/flutterw/lib/src/config.dart +++ b/packages/flutterw/lib/src/config.dart @@ -1,8 +1,9 @@ import 'dart:io'; import 'package:yaml/yaml.dart'; -import 'hook.dart'; - +/// FlutterwConfig +/// +/// contains a [scripts] map class FlutterwConfig { FlutterwConfig.empty() : yaml = null; @@ -12,26 +13,7 @@ class FlutterwConfig { final YamlMap? yaml; - Map get hooks { - return (yaml?['hooks'] as Map?) - ?.cast() - .map((key, value) { - if (value is List) { - return MapEntry( - key, - FlutterwHook.fromScripts( - name: key, - scripts: value.cast(), - )); - } else { - return MapEntry( - key, - FlutterwHook.fromPackage( - name: key, - package: value as String, - )); - } - }) ?? - {}; + Map get scripts { + return (yaml?['scripts'] as Map?)?.cast() ?? {}; } } diff --git a/packages/flutterw/lib/src/hook.dart b/packages/flutterw/lib/src/hook.dart index d7d2d04..73fca53 100644 --- a/packages/flutterw/lib/src/hook.dart +++ b/packages/flutterw/lib/src/hook.dart @@ -2,78 +2,80 @@ import 'dart:io'; import 'package:cli_hook/cli_hook.dart'; -/// Hook scripts that need args can add this placeholder. -const kFlutterwHookArgsPlaceholder = ''; +/// Script needs args can add this placeholder. +const _kArgsPlaceholder = ''; -/// Fluttew Hook +/// ScriptHook /// -/// A hook can be a list of scripts, -/// or a dart package. +/// A hook can be a list of executable scripts /// -class FlutterwHook extends Hook { +class ScriptHook extends Hook { final String name; final List scripts; - FlutterwHook.fromScripts({ + ScriptHook({ required this.name, - required this.scripts, - }) : verbose = false; - - final bool verbose; - - FlutterwHook.fromPackage({ - required this.name, - required String package, - bool global = false, - }) : verbose = true, - scripts = [ - [ - 'flutter', - 'pub', - if (global) 'global', - 'run', - package, - kFlutterwHookArgsPlaceholder, - ].join(' ') - ]; + required List scripts, + }) : scripts = scripts.map((e) => e.trim()).toList(); @override Future run(Iterable args) async { - stderr.writeln('Run hook $name'); + stderr.writeln('Running $name script'); for (String script in scripts) { await execScript(script, args); } } - /// Replace [kFlutterwHookArgsPlaceholder] in script to args, + /// Replace [_kArgsPlaceholder] in script to args, /// then execute this script. Future execScript(String script, Iterable args) async { - stderr.writeln(' └> $script'); final segments = script.split(RegExp(r'\s+')); - /// Assume is offen at end of script, + /// Assume is placed end of this script, /// search it from end to start var argsIndex = -1; for (var i = segments.length - 1; i >= 0; i--) { - if (segments[i] == kFlutterwHookArgsPlaceholder) { + if (segments[i] == _kArgsPlaceholder) { argsIndex = i; break; } } - /// Replace the + /// Replace the palceholder with runtime args. if (argsIndex != -1) { segments.replaceRange(argsIndex, argsIndex + 1, args); } final process = await Process.start( segments.removeAt(0), segments, - mode: verbose ? ProcessStartMode.inheritStdio : ProcessStartMode.normal, ); final code = await process.exitCode; if (code != 0) { exit(code); } } + + static Map transform(Map scripts) { + if (scripts.isEmpty) { + return {}; + } + return scripts.map((key, value) { + if (value is List) { + return MapEntry( + key, + ScriptHook( + name: key, + scripts: value.cast(), + )); + } else { + return MapEntry( + key, + ScriptHook( + name: key, + scripts: (value as String).split('&&'), + )); + } + }); + } } diff --git a/packages/flutterw/lib/src/runner.dart b/packages/flutterw/lib/src/runner.dart index d9d090e..aa0d3c8 100644 --- a/packages/flutterw/lib/src/runner.dart +++ b/packages/flutterw/lib/src/runner.dart @@ -5,10 +5,10 @@ import 'package:cli_util/cli_logging.dart'; import 'package:cli_wrapper/cli_wrapper.dart'; import 'commands/help.dart'; -import 'config.dart'; +import 'hook.dart'; import 'version.g.dart'; -/// A class that can run Flutterw with hooks system support. +/// A class that can run Flutterw with scripts and command hooks system support. /// /// To run a command, do: /// @@ -19,24 +19,24 @@ import 'version.g.dart'; /// ``` class FlutterwRunner extends CommandRunner with WrapperRunner, HookRunner { FlutterwRunner({ - this.config, + Map scripts = const {}, Logger? logger, }) : logger = logger ?? Logger.standard(), - super('flutterw', 'flutterw wraps flutter with command hooks system'); + hooks = ScriptHook.transform(scripts), + super('flutterw', + 'flutterw wraps flutter with scripts and command hooks support'); final Logger logger; - final FlutterwConfig? config; - @override String get originExecutableName => 'flutter'; @override - Map get hooks => config?.hooks ?? {}; + final Map hooks; @override String? get usageFooter => - '\nAnd use flutterw as flutter to enable hooks and plugins:\n' + '\nAnd use flutterw as flutter with scripts and command hooks support:\n' ' flutterw doctor\n' ' flutterw clean\n' ' flutterw pub get\n' diff --git a/packages/flutterw/pubspec.yaml b/packages/flutterw/pubspec.yaml index 9f445ff..cb76212 100644 --- a/packages/flutterw/pubspec.yaml +++ b/packages/flutterw/pubspec.yaml @@ -1,8 +1,7 @@ name: flutterw description: - Flutterw wraps flutter tool to support hooks system. - Hooks can be both scripts and dart package. - Adding global or project hook by using flutterw hook command. + Flutterw wraps flutter tool to support scripts and command hooks. + Hooks are pre, post and command scripts. version: 0.6.1 homepage: https://github.com/hyiso/flutterw repository: https://github.com/hyiso/flutterw/tree/main/packages/flutterw diff --git a/packages/flutterw/test/flutterw_test.dart b/packages/flutterw/test/flutterw_test.dart index af23f25..6c07e12 100644 --- a/packages/flutterw/test/flutterw_test.dart +++ b/packages/flutterw/test/flutterw_test.dart @@ -5,7 +5,7 @@ import 'package:test/test.dart'; void main() { test('flutterw should work.', () async { - final runner = FlutterwRunner(config: FlutterwConfig.empty()); + final runner = FlutterwRunner(); final dartToolDir = Directory('.dart_tool'); expect(dartToolDir.existsSync(), true); diff --git a/packages/flutterw_clean/example/pubspec.yaml b/packages/flutterw_clean/example/pubspec.yaml index 1f096e3..8534757 100644 --- a/packages/flutterw_clean/example/pubspec.yaml +++ b/packages/flutterw_clean/example/pubspec.yaml @@ -8,7 +8,7 @@ environment: sdk: '>=2.18.2 <3.0.0' flutter: ">=1.17.0" -hooks: +scripts: clean: flutterw_clean dependencies: diff --git a/packages/flutterw_hook/lib/src/commands.dart b/packages/flutterw_hook/lib/src/commands.dart index 7f1ab94..f0aafff 100644 --- a/packages/flutterw_hook/lib/src/commands.dart +++ b/packages/flutterw_hook/lib/src/commands.dart @@ -16,9 +16,6 @@ abstract class HookCommand extends Command { parents.add(runner!.executableName); return parents.reversed.join(' '); } - - @override - String get invocation => '$invocationPrefix [package]'; } class HookAddCommand extends HookCommand { @@ -28,6 +25,9 @@ class HookAddCommand extends HookCommand { @override String get name => 'add'; + @override + String get invocation => '$invocationPrefix [package]'; + @override FutureOr? run() async { await config.addHook( @@ -56,7 +56,7 @@ class HookRemoveCommand extends HookCommand { class HookListCommand extends HookCommand { @override - String get description => 'List all hooks'; + String get description => 'List all scripts'; @override String get name => 'list'; @@ -66,13 +66,13 @@ class HookListCommand extends HookCommand { @override FutureOr? run() async { - if (config.hooks.isEmpty) { - logger.stderr('No hooks.'); + if (config.scripts.isEmpty) { + logger.stderr('No scripts.'); return; } - if (config.hooks.isNotEmpty) { - logger.stderr('Project Hooks'); - for (var entry in config.hooks.entries) { + if (config.scripts.isNotEmpty) { + logger.stderr('Project Scripts'); + for (var entry in config.scripts.entries) { if (entry.value is String) { logger.stderr(' ${entry.key}: ${entry.value}'); } else if (entry.value is Iterable) { diff --git a/packages/flutterw_hook/lib/src/config.dart b/packages/flutterw_hook/lib/src/config.dart index 1c6fb91..d9e82a7 100644 --- a/packages/flutterw_hook/lib/src/config.dart +++ b/packages/flutterw_hook/lib/src/config.dart @@ -1,55 +1,32 @@ import 'dart:io'; import 'package:cli_util/cli_logging.dart'; -import 'package:yaml/yaml.dart'; +import 'package:flutterw/flutterw.dart'; import 'package:yaml_edit/yaml_edit.dart'; -class FlutterwHookConfig { - FlutterwHookConfig.fromFile(this.file); - - final File file; - +extension WrittableFlutterwConfig on FlutterwConfig { Logger get logger => Logger.standard(); - Map get hooks { - if (!file.existsSync()) { - return {}; - } - final YamlMap? yaml = loadYaml(file.readAsStringSync()); - return (yaml?['hooks'] as Map? ?? {}).cast(); - } + File get file => File('pubspec.yaml'); Future addHook({ required String name, required String package, bool overwrite = false, }) async { - final hook = hooks[name]; + final hook = scripts[name]; if (hook != null && !overwrite) { logger.stderr( - 'Hook [$name] has already been set, overwrite it by adding --overwrite flag.'); + 'Script [$name] has already been set, overwrite it by adding --overwrite flag.'); return; } logger.stderr('Set hook [$name] to package [$package].'); - if (!file.existsSync()) { - file.writeAsStringSync(''' -hooks: - $name: $package'''); - return; - } - final editor = YamlEditor(file.readAsStringSync()); + final editor = YamlEditor(await file.readAsString()); - if (hooks.isNotEmpty) { - editor.update(['hooks', name], package); + if (scripts.isNotEmpty) { + editor.update(['scripts', name], package); } else { - editor.update([ - 'hooks' - ], { - name: package, - }); - } - if (!file.existsSync()) { - file.createSync(recursive: true); + editor.update(['scripts'], {name: package}); } file.writeAsStringSync(editor.toString()); } @@ -57,20 +34,19 @@ hooks: Future removeHook({ required String name, }) async { - if (hooks[name] == null) { + if (scripts[name] == null) { logger.stderr(logger.ansi.error('Hook [$name] has not been set.')); return; } logger.stderr('Remove hook [$name].'); final editor = YamlEditor(file.readAsStringSync()); - if (hooks.keys.length > 1) { - editor.remove(['hooks', name]); + if (scripts.keys.length > 1) { + editor.remove(['scripts', name]); } else { - editor.remove(['hooks']); + editor.remove(['scripts']); } file.writeAsStringSync(editor.toString()); } } -FlutterwHookConfig get config => - FlutterwHookConfig.fromFile(File('pubspec.yaml')); +FlutterwConfig get config => FlutterwConfig.fromFile(File('pubspec.yaml')); diff --git a/packages/flutterw_hook/pubspec.yaml b/packages/flutterw_hook/pubspec.yaml index 29a57ad..5258175 100644 --- a/packages/flutterw_hook/pubspec.yaml +++ b/packages/flutterw_hook/pubspec.yaml @@ -12,6 +12,7 @@ environment: dependencies: args: ^2.3.1 cli_util: ^0.3.5 + flutterw: ^0.6.1 path: ^1.8.0 yaml: ^3.1.0 yaml_edit: ^2.0.3 diff --git a/packages/flutterw_hook/test/config_test.dart b/packages/flutterw_hook/test/config_test.dart index 9f85bd5..81d99f6 100644 --- a/packages/flutterw_hook/test/config_test.dart +++ b/packages/flutterw_hook/test/config_test.dart @@ -2,21 +2,21 @@ import 'package:flutterw_hook/flutterw_hook.dart'; import 'package:test/test.dart'; void main() { - group('FlutterwHookConfig', () { + group('WrittableFlutterwConfig', () { test('addHook should work', () async { - expect(config.hooks.isEmpty, true); + expect(config.scripts.isEmpty, true); await config.addHook(name: 'hook', package: 'flutterw_hook'); - expect(config.hooks.isNotEmpty, true); - expect(config.hooks['hook'] != null, true); - expect(config.hooks['hook'], equals('flutterw_hook')); + expect(config.scripts.isNotEmpty, true); + expect(config.scripts['hook'] != null, true); + expect(config.scripts['hook'], equals('flutterw_hook')); }); test('removeHook should work', () async { - expect(config.hooks.isNotEmpty, true); - expect(config.hooks['hook'] != null, true); - expect(config.hooks['hook'], equals('flutterw_hook')); + expect(config.scripts.isNotEmpty, true); + expect(config.scripts['hook'] != null, true); + expect(config.scripts['hook'], equals('flutterw_hook')); await config.removeHook(name: 'hook'); - expect(config.hooks.isEmpty, true); + expect(config.scripts.isEmpty, true); }); }); } From c9ddb9c7f9088795759e9e8eab812b59ebc89c2e Mon Sep 17 00:00:00 2001 From: hyiso Date: Sat, 14 Jan 2023 19:36:59 +0800 Subject: [PATCH 2/2] docs: update docs about scripts --- README.md | 18 +- docs.json | 3 +- docs/adding-custom-command.mdx | 34 --- docs/command-hooks.mdx | 53 +++++ docs/getting-started.mdx | 47 ++-- docs/hooks.mdx | 69 ------ docs/index.mdx | 9 +- packages/flutterw/README.md | 21 +- packages/flutterw_hook/.gitignore | 6 - packages/flutterw_hook/CHANGELOG.md | 9 - packages/flutterw_hook/LICENSE | 201 ------------------ packages/flutterw_hook/README.md | 39 ---- packages/flutterw_hook/analysis_options.yaml | 30 --- packages/flutterw_hook/bin/flutterw_hook.dart | 10 - packages/flutterw_hook/lib/flutterw_hook.dart | 2 - packages/flutterw_hook/lib/src/commands.dart | 87 -------- packages/flutterw_hook/lib/src/config.dart | 52 ----- packages/flutterw_hook/pubspec.yaml | 22 -- packages/flutterw_hook/test/config_test.dart | 22 -- 19 files changed, 98 insertions(+), 636 deletions(-) delete mode 100644 docs/adding-custom-command.mdx create mode 100644 docs/command-hooks.mdx delete mode 100644 docs/hooks.mdx delete mode 100644 packages/flutterw_hook/.gitignore delete mode 100644 packages/flutterw_hook/CHANGELOG.md delete mode 100644 packages/flutterw_hook/LICENSE delete mode 100644 packages/flutterw_hook/README.md delete mode 100644 packages/flutterw_hook/analysis_options.yaml delete mode 100644 packages/flutterw_hook/bin/flutterw_hook.dart delete mode 100644 packages/flutterw_hook/lib/flutterw_hook.dart delete mode 100644 packages/flutterw_hook/lib/src/commands.dart delete mode 100644 packages/flutterw_hook/lib/src/config.dart delete mode 100644 packages/flutterw_hook/pubspec.yaml delete mode 100644 packages/flutterw_hook/test/config_test.dart diff --git a/README.md b/README.md index eb8a116..b1f9837 100644 --- a/README.md +++ b/README.md @@ -26,21 +26,23 @@ Also, the Flutter Tool does not give chance to do extra work during command runn To solve these (and other related) problems, flutterw is created. -**Flutterw wraps the flutter tool to support command hooks system.** -**`pre` and `post` hooks enable you to do extra work before and after command running** -**and `command` hooks enable you to customize command behavior.** +**Flutterw wraps flutter tool to support scripts and command hooks.** +**Hooks are pre, post and command scripts.** +**`pre` and `post` scripts enable you to do extra work before and after running command** +**and `command` scripts enable you to customize command behavior.** ### What can Flutterw do? + - Dispatch arguments to flutter tool when no command hook configured. -- `pre` hooks are executed before running command. -- `post` hooks are executed after running command. -- `command` hooks are executed to replace original command. -- Hooks can also be packages in [Pub](https://pub.dev) +- `pre` scripts are executed before running command. +- `post` scripts are executed after running command. +- `command` scripts are executed to replace original command. +- Command scripts can be packages in [Pub](https://pub.dev/packages?q=flutterw) - packages created by flutterw author - [flutterw_clean](https://pub.dev/packages/flutterw_clean) - [flutterw_hook](https://pub.dev/packages/flutterw_hook) - packages created by other developers. -- Add custom commands to `flutterw` dart package. +- Add custom to `flutterw`. ## Install diff --git a/docs.json b/docs.json index 7cf0eed..688f169 100644 --- a/docs.json +++ b/docs.json @@ -7,7 +7,6 @@ "sidebar": [ ["Overview", "/"], ["Getting Started", "/getting-started"], - ["Hooks", "/hooks"], - ["Adding Custom Command", "/adding-custom-command"] + ["Command Hooks", "/command-hooks"] ] } \ No newline at end of file diff --git a/docs/adding-custom-command.mdx b/docs/adding-custom-command.mdx deleted file mode 100644 index 3e3bdc8..0000000 --- a/docs/adding-custom-command.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Adding Custom Command -description: "Learn how to add custom commands to Flutterw." ---- - -# Custom Command - -Adding custom commands to `Flutterw` is so easy with `command` package hook. - -For Example, We want to use `scripts` shorthands, we can add a custom command with package [derry](https://pub.dev/packages/derry). - -First, add derry to `dev_dependencies` in `pubspec.yaml`: - -```yaml -dev_dependencies: - derry: latest -``` - -Then, add the custom command name (here we use `rs`) to derry under `hooks` in `pubspec.yaml`: - -```yaml -hooks: - rs: derry -``` - -According to derry's usage documentation, we add some scripts to `pubspec.yaml`: - -```yaml -scripts: - generate: flutter pub run build_runner build --delete-conflicting-outputs - build:aar: flutter build aar --no-debug --no-profile -``` - -Now, we can just run `flutterw rs generate`、 `flutterw rs build:aar`. \ No newline at end of file diff --git a/docs/command-hooks.mdx b/docs/command-hooks.mdx new file mode 100644 index 0000000..f97b41c --- /dev/null +++ b/docs/command-hooks.mdx @@ -0,0 +1,53 @@ +--- +title: Command Hooks +description: "Learn more about all the command hooks system in Flutterw." +--- + +# Command Hook Script + +A command hook is a script with name of flutter builtin commands. For example: + +```yaml +scripts: + clean: flutter pub run flutterw_clean +``` +When running `flutterw clean`, `flutter pub run flutterw_clean` will be executed instead. + +## Pre & Post Command Hook Script + +Each Flutter command can be hooked with `pre:command` and `post:comand`: + +```yaml +scripts: + pre:clean: echo 'pre clean' + post:clean: echo 'post clean' +``` +When running `flutterw clean`, `pre:clean` will be executed first, then the `clean` command runs, +and `post:clean` will be executed finally. + +## Sub Command Hook + +For sub command, hook name is command parts joined with colon(`:`) + +```yaml +scripts: + pre:build:aar: # This is pre hook for 'flutterw build aar' + build:aar: # This is command hook 'flutterw build aar' + post:build:aar: # This is post hook for 'flutterw build aar' +``` + +# Script Args + +Scripts don't take arguments from running command by default. + +If a command hook script needs to use the command arguments, use a `` placeholder. + +For example: + +```yaml +scripts: + pre:build: + - dart ./scripts/pre_build.dart # arguments passed to build command will be here. + post:build: + - dart ./scripts/post_build.dart # arguments passed to build command will be here. +``` \ No newline at end of file diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx index b2a4f78..994b418 100644 --- a/docs/getting-started.mdx +++ b/docs/getting-started.mdx @@ -15,45 +15,34 @@ Flutterw can be installed as a global package via [pub.dev](https://pub.dev/): dart pub global activate flutterw ``` -### Setup +## Setup Scripts -To set up your project to use Flutterw, create a `pubspec.yaml` file in the root of the project. +After installed, flutterw can be used just as flutter tool. -Within the `pubspec.yaml` file, add `hooks` fields: +To use flutterw with custom scripts, just add `scripts` fields within the `pubspec.yaml` file: ```yaml -hooks: - pre:clean: - - echo 'before clean' - clean: - - rm -fr .dart_tool - post:clean: - - echo 'after clean' -``` - -The `pre:command` hook scripts will be executed in order **before** command running. - -The `command` hook scripts will be executed in order to replace original flutter command. - -The `post:command` hook scripts will be executed in order **after** command running. +scripts: + generate: flutter pub run build_runner build --delete-conflicting-outputs +``` -## Next steps - -Besides shell scripts, you can set the took to a package listed in `dev_dependencies`. - -Flutterw will internally tranlate the package to `dart pub run package`. +Then running `flutterw generate` will execute `flutter pub run build_runner build --delete-conflicting-outputs`. -For example, your `pubspec.yaml` has `flutterw_clean` in `dev_dependencies`: +A Script's value can be multi executable string joined with `&&`, or just a spearated list. ```yaml -dev_dependencies: - flutter_clean: any +scripts: + pull: git pull && git submodule update --init --recursive ``` -Then set hook `clean` to package `flutter_clean` in `pubspec.yaml`: +or ```yaml -hooks: - clean: flutterw_clean +scripts: + pull: + - git pull + - git submodule update --init --recursive ``` +When running `flutterw pull`, this two scripts will be executable by in roder. + -When running `flutterw clean`, package `flutterw_clean` will be executed. \ No newline at end of file +**Notice: scripts' names (eg: generate and pull) must not be the same with flutter command name, or they will be considered as a command hooks.** \ No newline at end of file diff --git a/docs/hooks.mdx b/docs/hooks.mdx deleted file mode 100644 index 0e2c4fd..0000000 --- a/docs/hooks.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Hooks System -description: "Learn more about all the hooks system in Flutterw." ---- - -# Hook Name - -Each Flutter command can be hooked with `pre:command`, `command` and `post:comand`: - -```yaml -hooks: - pre:clean: - clean: - post:clean: -``` - -## Sub command - -For sub command, hook name is command parts joined with colon(`:`) - -```yaml -hooks: - pre:pub:get: # This is pre hook for command 'pub get' - post:pub:get: # This is post hook for command 'pub get' -``` - -# Hook Type - -Basiclly, hooks are executable shell scripts. - -```yaml -hooks: - pre:clean: - - echo 'pre clean 1' - - echo 'pre clean 2' - clean: - - echo 'clean' - post:clean: - - echo 'post clean' -``` - -## Package Hook - -Besides shell scripts, a hook can also be a dart package. - -```yaml -hooks: - clean: flutterw_clean -``` -**Note: make sure `flutterw_clean` is in `dev_dependencies` of project's `pubspec.yaml`. - - -# Hook Args - -Hook scripts don't take arguments from running command by default. - -If a hook script needs to use the command arguments, use a `` placeholder. - -For example: - -```yaml -hooks: - pre:build: - - dart ./scripts/pre_build.dart # arguments passed to build command will be here. - post:build: - - dart ./scripts/post_build.dart # arguments passed to build command will be here. -``` - -Package type hook will automatically add `` placeholder after translated to script internally. \ No newline at end of file diff --git a/docs/index.mdx b/docs/index.mdx index b231d31..7d2e033 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -18,14 +18,15 @@ To solve these (and other related) problems, flutterw is created. Features include: - Dispatch arguments to flutter tool when no command hook configured. -- `pre` hooks are executed before running command. -- `post` hooks are executed after running command. -- `command` hooks are executed to replace original command. -- Hooks can also be packages in [Pub](https://pub.dev/packages?q=flutterw) +- `pre` scripts are executed before running command. +- `post` scripts are executed after running command. +- `command` scripts are executed to replace original command. +- Command scripts can be packages in [Pub](https://pub.dev/packages?q=flutterw) - packages created by flutterw author - [flutterw_clean](https://pub.dev/packages/flutterw_clean) - [flutterw_hook](https://pub.dev/packages/flutterw_hook) - packages created by other developers. +- Add custom to `flutterw`. ## Projects using Flutterw diff --git a/packages/flutterw/README.md b/packages/flutterw/README.md index 1a16274..04c66d5 100644 --- a/packages/flutterw/README.md +++ b/packages/flutterw/README.md @@ -26,22 +26,23 @@ Also, the Flutter Tool does not give chance to do extra work during command runn To solve these (and other related) problems, flutterw is created. -**Flutterw wraps the flutter tool to support command hooks system.** -**`pre` and `post` hooks enable you to do extra work before and after command running** -**and `command` hooks enable you to customize command behavior.** +**Flutterw wraps flutter tool to support scripts and command hooks.** +**Hooks are pre, post and command scripts.** +**`pre` and `post` scripts enable you to do extra work before and after running command** +**and `command` scripts enable you to customize command behavior.** ## What can Flutterw do? - Dispatch arguments to flutter tool when no command hook configured. -- `pre` hooks are executed before running command. -- `post` hooks are executed after running command. -- `command` hooks are executed to replace original command. -- Hooks can also be packages in [Pub](https://pub.dev/packages?q=flutterw) +- `pre` scripts are executed before running command. +- `post` scripts are executed after running command. +- `command` scripts are executed to replace original command. +- Command scripts can be packages in [Pub](https://pub.dev/packages?q=flutterw) - packages created by flutterw author - [flutterw_clean](https://pub.dev/packages/flutterw_clean) - [flutterw_hook](https://pub.dev/packages/flutterw_hook) - packages created by other developers. -- Add custom commands to `flutterw` dart package. +- Add custom to `flutterw`. ## Who is using Flutterw? @@ -60,7 +61,7 @@ Full commands list and args can be viewed by running flutterw -h. ``` > flutterw -h -flutterw wraps flutter tool with advanced usage. +flutterw wraps flutter with scripts and command hooks support Usage: flutterw [arguments] @@ -72,7 +73,7 @@ Available commands: Run "flutterw help " for more information about a command. -And use flutterw as flutter to enable hooks and plugins: +And use flutterw as flutter with scripts and command hooks support: flutterw doctor flutterw clean flutterw pub get diff --git a/packages/flutterw_hook/.gitignore b/packages/flutterw_hook/.gitignore deleted file mode 100644 index 3c8a157..0000000 --- a/packages/flutterw_hook/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# Files and directories created by pub. -.dart_tool/ -.packages - -# Conventional directory for build output. -build/ diff --git a/packages/flutterw_hook/CHANGELOG.md b/packages/flutterw_hook/CHANGELOG.md deleted file mode 100644 index 1351a4e..0000000 --- a/packages/flutterw_hook/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -## 0.2.0 - - - Upgrade flutterw version - -## 0.1.0 - -- `add ` to add package hook. -- `remove ` to remove hook package. -- `list` to list all hook. diff --git a/packages/flutterw_hook/LICENSE b/packages/flutterw_hook/LICENSE deleted file mode 100644 index 306f40f..0000000 --- a/packages/flutterw_hook/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2022 hyiso Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/packages/flutterw_hook/README.md b/packages/flutterw_hook/README.md deleted file mode 100644 index 29762c1..0000000 --- a/packages/flutterw_hook/README.md +++ /dev/null @@ -1,39 +0,0 @@ -## About - -This is a hook package for [flutterw](../flutterw), the usage is to manage package hooks. - -## Install - -First, add this package in `dev_dependencies` in project's `pubspec.yaml`. -```yaml -dev_dependencies: - flutterw_hook: any -``` -Then, add this package to `hooks` in project's `pubspec.yaml`. -```yaml -hooks: - hook: flutterw_hook -``` -Now, you can run `flutterw hook [arguemnts]` to manage hooks. - -## Manage Hooks - -Shell scripts hooks can be managed by modifying project's `pubspec.yaml` - -Package hooks can be managed by using `flutterw hook [arguemnts]`. - -``` -> flutterw hook -h - -Manage Flutterw Hooks. - -Usage: flutterw hook [arguments] --h, --help Print this usage information. - -Available subcommands: - add Add a hook - list List all hooks - remove Remove a hook - -Run "flutterw help hook" to see global options. -``` diff --git a/packages/flutterw_hook/analysis_options.yaml b/packages/flutterw_hook/analysis_options.yaml deleted file mode 100644 index dee8927..0000000 --- a/packages/flutterw_hook/analysis_options.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# This file configures the static analysis results for your project (errors, -# warnings, and lints). -# -# This enables the 'recommended' set of lints from `package:lints`. -# This set helps identify many issues that may lead to problems when running -# or consuming Dart code, and enforces writing Dart using a single, idiomatic -# style and format. -# -# If you want a smaller set of lints you can change this to specify -# 'package:lints/core.yaml'. These are just the most critical lints -# (the recommended set includes the core lints). -# The core lints are also what is used by pub.dev for scoring packages. - -include: package:lints/recommended.yaml - -# Uncomment the following section to specify additional rules. - -# linter: -# rules: -# - camel_case_types - -# analyzer: -# exclude: -# - path/to/excluded/files/** - -# For more information about the core and recommended set of lints, see -# https://dart.dev/go/core-lints - -# For additional information about configuring this file, see -# https://dart.dev/guides/language/analysis-options diff --git a/packages/flutterw_hook/bin/flutterw_hook.dart b/packages/flutterw_hook/bin/flutterw_hook.dart deleted file mode 100644 index 7c535e1..0000000 --- a/packages/flutterw_hook/bin/flutterw_hook.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:args/command_runner.dart'; -import 'package:flutterw_hook/flutterw_hook.dart'; - -void main(List arguments) { - CommandRunner('flutterw hook', 'Manage Flutterw Hooks') - ..addCommand(HookAddCommand()) - ..addCommand(HookListCommand()) - ..addCommand(HookRemoveCommand()) - ..run(arguments); -} diff --git a/packages/flutterw_hook/lib/flutterw_hook.dart b/packages/flutterw_hook/lib/flutterw_hook.dart deleted file mode 100644 index a3ad7f1..0000000 --- a/packages/flutterw_hook/lib/flutterw_hook.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'src/commands.dart'; -export 'src/config.dart'; diff --git a/packages/flutterw_hook/lib/src/commands.dart b/packages/flutterw_hook/lib/src/commands.dart deleted file mode 100644 index f0aafff..0000000 --- a/packages/flutterw_hook/lib/src/commands.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'dart:async'; - -import 'package:args/command_runner.dart'; -import 'package:cli_util/cli_logging.dart'; - -import 'config.dart'; - -abstract class HookCommand extends Command { - Logger get logger => Logger.standard(); - - String get invocationPrefix { - var parents = [name]; - for (var command = parent; command != null; command = command.parent) { - parents.add(command.name); - } - parents.add(runner!.executableName); - return parents.reversed.join(' '); - } -} - -class HookAddCommand extends HookCommand { - @override - String get description => 'Add a hook'; - - @override - String get name => 'add'; - - @override - String get invocation => '$invocationPrefix [package]'; - - @override - FutureOr? run() async { - await config.addHook( - name: argResults!.rest.first, package: argResults!.rest.last); - } -} - -class HookRemoveCommand extends HookCommand { - @override - String get description => 'Remove a hook'; - - @override - String get name => 'remove'; - - @override - List get aliases => ['rm']; - - @override - String get invocation => '$invocationPrefix '; - - @override - FutureOr? run() async { - await config.removeHook(name: argResults!.rest.first); - } -} - -class HookListCommand extends HookCommand { - @override - String get description => 'List all scripts'; - - @override - String get name => 'list'; - - @override - List get aliases => ['ls']; - - @override - FutureOr? run() async { - if (config.scripts.isEmpty) { - logger.stderr('No scripts.'); - return; - } - if (config.scripts.isNotEmpty) { - logger.stderr('Project Scripts'); - for (var entry in config.scripts.entries) { - if (entry.value is String) { - logger.stderr(' ${entry.key}: ${entry.value}'); - } else if (entry.value is Iterable) { - logger.stderr(' ${entry.key}: '); - for (String script in entry.value as Iterable) { - logger.stderr(' - $script'); - } - } - } - } - } -} diff --git a/packages/flutterw_hook/lib/src/config.dart b/packages/flutterw_hook/lib/src/config.dart deleted file mode 100644 index d9e82a7..0000000 --- a/packages/flutterw_hook/lib/src/config.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:io'; - -import 'package:cli_util/cli_logging.dart'; -import 'package:flutterw/flutterw.dart'; -import 'package:yaml_edit/yaml_edit.dart'; - -extension WrittableFlutterwConfig on FlutterwConfig { - Logger get logger => Logger.standard(); - - File get file => File('pubspec.yaml'); - - Future addHook({ - required String name, - required String package, - bool overwrite = false, - }) async { - final hook = scripts[name]; - if (hook != null && !overwrite) { - logger.stderr( - 'Script [$name] has already been set, overwrite it by adding --overwrite flag.'); - return; - } - logger.stderr('Set hook [$name] to package [$package].'); - final editor = YamlEditor(await file.readAsString()); - - if (scripts.isNotEmpty) { - editor.update(['scripts', name], package); - } else { - editor.update(['scripts'], {name: package}); - } - file.writeAsStringSync(editor.toString()); - } - - Future removeHook({ - required String name, - }) async { - if (scripts[name] == null) { - logger.stderr(logger.ansi.error('Hook [$name] has not been set.')); - return; - } - logger.stderr('Remove hook [$name].'); - final editor = YamlEditor(file.readAsStringSync()); - if (scripts.keys.length > 1) { - editor.remove(['scripts', name]); - } else { - editor.remove(['scripts']); - } - file.writeAsStringSync(editor.toString()); - } -} - -FlutterwConfig get config => FlutterwConfig.fromFile(File('pubspec.yaml')); diff --git a/packages/flutterw_hook/pubspec.yaml b/packages/flutterw_hook/pubspec.yaml deleted file mode 100644 index 5258175..0000000 --- a/packages/flutterw_hook/pubspec.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: flutterw_hook -description: - This is a hook package for flutterw] - You can usage this package to manage flutterw's package hooks. -version: 0.2.0 -homepage: https://github.com/hyiso/flutterw -repository: https://github.com/hyiso/flutterw/tree/main/packages/flutterw_clean - -environment: - sdk: '>=2.18.6 <3.0.0' - -dependencies: - args: ^2.3.1 - cli_util: ^0.3.5 - flutterw: ^0.6.1 - path: ^1.8.0 - yaml: ^3.1.0 - yaml_edit: ^2.0.3 - -dev_dependencies: - lints: ^2.0.0 - test: ^1.16.0 diff --git a/packages/flutterw_hook/test/config_test.dart b/packages/flutterw_hook/test/config_test.dart deleted file mode 100644 index 81d99f6..0000000 --- a/packages/flutterw_hook/test/config_test.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutterw_hook/flutterw_hook.dart'; -import 'package:test/test.dart'; - -void main() { - group('WrittableFlutterwConfig', () { - test('addHook should work', () async { - expect(config.scripts.isEmpty, true); - await config.addHook(name: 'hook', package: 'flutterw_hook'); - expect(config.scripts.isNotEmpty, true); - expect(config.scripts['hook'] != null, true); - expect(config.scripts['hook'], equals('flutterw_hook')); - }); - - test('removeHook should work', () async { - expect(config.scripts.isNotEmpty, true); - expect(config.scripts['hook'] != null, true); - expect(config.scripts['hook'], equals('flutterw_hook')); - await config.removeHook(name: 'hook'); - expect(config.scripts.isEmpty, true); - }); - }); -}