getInOrderOfExecution function

Future<List<ParallelTasks>> getInOrderOfExecution(
  1. List<TaskInvocation> invocations, [
  2. bool forceTasks = false,
  3. bool showTasks = false,
  4. DeletionTasksByTask tasksAffectedByDeletion = const {},
])

Get the tasks in the order that they should be executed, taking into account their dependencies and phases.

To know which tasks must run, call TaskWithStatus.mustRun on each returned task.

Notice that when a task is out-of-date, all of its dependents also become out-of-date.

Implementation

Future<List<ParallelTasks>> getInOrderOfExecution(
    List<TaskInvocation> invocations,
    [bool forceTasks = false,
    bool showTasks = false,
    DeletionTasksByTask tasksAffectedByDeletion = const {}]) async {
  // first of all, re-order tasks so that dependencies are in order
  invocations.sort((a, b) => a.task.compareTo(b.task));

  final result = <ParallelTasks>[];

  void addTaskToParallelTasks(TaskWithStatus taskWithStatus) {
    final canRunInPreviousGroup =
        result.isNotEmpty && result.last.canInclude(taskWithStatus.task);
    if (canRunInPreviousGroup) {
      result.last.add(taskWithStatus);
    } else {
      result.add(ParallelTasks()..add(taskWithStatus));
    }
  }

  final taskStatuses = <String, TaskWithStatus>{};

  Future<void> addInvocation(TaskInvocation invocation) async {
    final taskWithStatus = await _createTaskWithStatus(
        invocation, taskStatuses, forceTasks, tasksAffectedByDeletion);
    taskStatuses[invocation.name] = taskWithStatus;
    addTaskToParallelTasks(taskWithStatus);
  }

  final seenTasks = <String>{};

  for (final inv in invocations) {
    for (final dep in inv.task.dependencies) {
      if (seenTasks.add(dep.name)) await addInvocation(TaskInvocation(dep));
    }
    if (seenTasks.add(inv.name)) await addInvocation(inv);
  }

  return result;
}