run method

Future<int> run(
  1. String target,
  2. Future<int> action(
    1. HookStack stack
    ), {
  3. String? hooksFrom,
  4. HookOrder order = HookOrder.standard,
})

Runs action for target between its hooks, and returns the first non-zero exit code, or 0.

With hooksFrom, the target also uses the hooks of that script: pre:<hooksFrom> runs before pre:<target>, and post:<target> runs before post:<hooksFrom>. Shared hooks run once when they apply to either name.

action receives the stack that its child processes should inherit.

Implementation

Future<int> run(
  String target,
  Future<int> Function(HookStack stack) action, {
  String? hooksFrom,
  HookOrder order = HookOrder.standard,
}) async {
  if (isHookName(target)) {
    return action(stack);
  }

  final names = {?hooksFrom, target}.toList();
  Script? shared(String name) {
    final hook = scripts[name];
    return hook != null && names.any(hook.appliesTo) ? hook : null;
  }

  final before = shared('before');
  final after = shared('after');
  final pre = [for (final name in names) ?scripts['pre:$name']];
  final post = [for (final name in names.reversed) ?scripts['post:$name']];

  final all = [?before, ...pre, ...post, ?after];
  final childStack = stack.adding(rootPath, all.map((hook) => hook.name));

  final sequence = <Future<int> Function()>[
    if (order == HookOrder.standard) ...[
      if (before != null) () => _runHook(before, childStack),
      for (final hook in pre) () => _runHook(hook, childStack),
      () => action(childStack),
    ] else ...[
      for (final hook in pre) () => _runHook(hook, childStack),
      () => action(childStack),
      if (before != null) () => _runHook(before, childStack),
    ],
    for (final hook in post) () => _runHook(hook, childStack),
    if (after != null) () => _runHook(after, childStack),
  ];

  for (final step in sequence) {
    final exitCode = await step();
    if (exitCode != 0) {
      return exitCode;
    }
  }
  return 0;
}