zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

task.ex (4584B)


      1 defmodule Credo.Execution.Task do
      2   @moduledoc """
      3   A Task is a step in a pipeline, which is given an `Credo.Execution` struct and must return one as well.
      4 
      5   Tasks in a pipeline are only called if they are not "halted" (see `Credo.Execution.halt/2`).
      6 
      7   It implements a `call/1` or `call/2` callback, which is called with the `Credo.Execution` struct
      8   as first parameter (and the Task's options as the second in case of `call/2`).
      9   """
     10 
     11   @typedoc false
     12   @type t :: module
     13 
     14   @doc """
     15   Is called by the pipeline and contains the Task's actual code.
     16 
     17       defmodule FooTask do
     18         use Credo.Execution.Task
     19 
     20         def call(exec) do
     21           IO.inspect(exec)
     22         end
     23       end
     24 
     25   The `call/1` functions receives an `exec` struct and must return a (modified) `Credo.Execution`.
     26   """
     27   @callback call(exec :: Credo.Execution.t()) :: Credo.Execution.t()
     28 
     29   @doc """
     30   Works like `call/1`, but receives the options, which are optional when registering the Task, as second argument.
     31 
     32       defmodule FooTask do
     33         use Credo.Execution.Task
     34 
     35         def call(exec, opts) do
     36           IO.inspect(opts)
     37 
     38           exec
     39         end
     40       end
     41 
     42   """
     43   @callback call(exec :: Credo.Execution.t(), opts :: Keyword.t()) :: Credo.Execution.t()
     44 
     45   @doc """
     46   Gets called if `call` holds the execution via `Credo.Execution.halt/1` or `Credo.Execution.halt/2`.
     47   """
     48   @callback error(exec :: Credo.Execution.t()) :: Credo.Execution.t()
     49 
     50   @doc """
     51   Works like `error/1`, but receives the options, which were given during pipeline registration, as second argument.
     52   """
     53   @callback error(exec :: Credo.Execution.t(), opts :: Keyword.t()) :: Credo.Execution.t()
     54 
     55   require Logger
     56 
     57   alias Credo.Execution
     58   alias Credo.Execution.ExecutionTiming
     59 
     60   defmacro __using__(_opts \\ []) do
     61     quote do
     62       @behaviour Credo.Execution.Task
     63 
     64       import Credo.Execution
     65 
     66       alias Credo.CLI.Output.UI
     67       alias Credo.Execution
     68 
     69       @impl true
     70       def call(%Execution{halted: false} = exec) do
     71         exec
     72       end
     73 
     74       @impl true
     75       def call(%Execution{halted: false} = exec, opts) do
     76         call(exec)
     77       end
     78 
     79       @impl true
     80       def error(exec) do
     81         case Execution.get_halt_message(exec) do
     82           "" <> halt_message ->
     83             command_name = Execution.get_command_name(exec) || "credo"
     84 
     85             UI.warn([:red, "** (#{command_name}) ", halt_message])
     86 
     87           _ ->
     88             IO.warn("Execution halted during #{__MODULE__}!")
     89         end
     90 
     91         exec
     92       end
     93 
     94       @impl true
     95       def error(exec, _opts) do
     96         error(exec)
     97       end
     98 
     99       defoverridable call: 1
    100       defoverridable call: 2
    101       defoverridable error: 1
    102       defoverridable error: 2
    103     end
    104   end
    105 
    106   @doc false
    107   def run(task, exec, opts \\ [])
    108 
    109   def run(task, %Credo.Execution{debug: true} = exec, opts) do
    110     run_with_timing(task, exec, opts)
    111   end
    112 
    113   def run(task, %Execution{} = exec, opts) do
    114     do_run(task, exec, opts)
    115   end
    116 
    117   def run(_task, exec, _opts) do
    118     IO.warn(
    119       "Expected second parameter of Task.run/3 to match %Credo.Execution{}, " <>
    120         "got: #{inspect(exec)}"
    121     )
    122 
    123     exec
    124   end
    125 
    126   defp do_run(task, %Credo.Execution{halted: false} = exec, opts) do
    127     old_parent_task = exec.parent_task
    128     old_current_task = exec.current_task
    129 
    130     exec =
    131       exec
    132       |> Execution.set_parent_and_current_task(exec.current_task, task)
    133       |> task.call(opts)
    134       |> Execution.ensure_execution_struct("#{task}.call/2")
    135 
    136     if exec.halted do
    137       exec
    138       |> task.error(opts)
    139       |> Execution.set_parent_and_current_task(old_parent_task, old_current_task)
    140     else
    141       Execution.set_parent_and_current_task(exec, old_parent_task, old_current_task)
    142     end
    143   end
    144 
    145   defp do_run(_task, exec, _opts) do
    146     exec
    147   end
    148 
    149   #
    150 
    151   defp run_with_timing(task, exec, opts) do
    152     context_tuple = {:task, exec, task, opts}
    153     log(:call_start, context_tuple)
    154 
    155     {started_at, time, exec} = ExecutionTiming.run(&do_run/3, [task, exec, opts])
    156 
    157     log(:call_end, context_tuple, time)
    158 
    159     ExecutionTiming.append(exec, [task: task, parent_task: exec.parent_task], started_at, time)
    160 
    161     exec
    162   end
    163 
    164   defp log(:call_start, {:task, _exec, task, _opts}) do
    165     Logger.info("Calling #{task} ...")
    166   end
    167 
    168   defp log(:call_end, {:task, _exec, task, _opts}, time) do
    169     Logger.info("Finished #{task} in #{format_time(time)} ...")
    170   end
    171 
    172   defp format_time(time) do
    173     cond do
    174       time > 1_000_000 ->
    175         "#{div(time, 1_000_000)}s"
    176 
    177       time > 1_000 ->
    178         "#{div(time, 1_000)}ms"
    179 
    180       true ->
    181         "#{time}μs"
    182     end
    183   end
    184 end