mirror of
https://github.com/ash-project/reactor.git
synced 2024-09-19 12:53:19 +12:00
feat: Add collect
step entity. (#53)
This change introduces the `collect` step entity to the DSL. It is simply a wrapper around `Reactor.Step.ReturnAllArguments`, but provides the convenience of being able to group together arguments into a single structure for passing into other steps.
This commit is contained in:
parent
61d7d3422b
commit
f67173b76f
5 changed files with 133 additions and 4 deletions
|
@ -10,6 +10,8 @@ spark_locals_without_parens = [
|
|||
around: 3,
|
||||
async?: 1,
|
||||
before_all: 1,
|
||||
collect: 1,
|
||||
collect: 2,
|
||||
compensate: 1,
|
||||
compose: 2,
|
||||
compose: 3,
|
||||
|
|
|
@ -18,12 +18,13 @@ defmodule Reactor.Dsl do
|
|||
],
|
||||
entities: [
|
||||
Dsl.Around.__entity__(),
|
||||
Dsl.Collect.__entity__(),
|
||||
Dsl.Compose.__entity__(),
|
||||
Dsl.Debug.__entity__(),
|
||||
Dsl.Group.__entity__(),
|
||||
Dsl.Input.__entity__(),
|
||||
Dsl.Step.__entity__(),
|
||||
Dsl.Switch.__entity__(),
|
||||
Dsl.Compose.__entity__()
|
||||
Dsl.Switch.__entity__()
|
||||
],
|
||||
top_level?: true,
|
||||
patchable?: true
|
||||
|
|
87
lib/reactor/dsl/collect.ex
Normal file
87
lib/reactor/dsl/collect.ex
Normal file
|
@ -0,0 +1,87 @@
|
|||
defmodule Reactor.Dsl.Collect do
|
||||
@moduledoc """
|
||||
The struct used to store collect DSL entities.
|
||||
|
||||
See `d:Reactor.collect`.
|
||||
"""
|
||||
|
||||
defstruct __identifier__: nil,
|
||||
arguments: [],
|
||||
name: nil,
|
||||
transform: nil
|
||||
|
||||
alias Reactor.{Builder, Dsl, Step}
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
arguments: [Dsl.Argument.t()],
|
||||
name: atom,
|
||||
transform: nil | (any -> any),
|
||||
__identifier__: any
|
||||
}
|
||||
|
||||
@doc false
|
||||
def __entity__,
|
||||
do: %Spark.Dsl.Entity{
|
||||
name: :collect,
|
||||
describe: """
|
||||
A Reactor step which simply collects and returns it's arguments.
|
||||
|
||||
Arguments can optionally be transformed before returning.
|
||||
""",
|
||||
examples: [
|
||||
"""
|
||||
collect :latest_release_uri do
|
||||
argument :repository, input(:repository)
|
||||
argument :organisation, input(:organisation)
|
||||
|
||||
transform fn inputs ->
|
||||
%{uri: "https://api.github.com/repos/\#{inputs.organisation}/\#{inputs.repository}/releases/latest"}
|
||||
end
|
||||
end
|
||||
"""
|
||||
],
|
||||
args: [:name],
|
||||
target: __MODULE__,
|
||||
identifier: :name,
|
||||
entities: [arguments: [Dsl.Argument.__entity__(), Dsl.WaitFor.__entity__()]],
|
||||
recursive_as: :steps,
|
||||
schema: [
|
||||
name: [
|
||||
type: :atom,
|
||||
required: true,
|
||||
doc: """
|
||||
A unique name for the step.
|
||||
|
||||
This is used when choosing the return value of the Reactor and for arguments into other steps.
|
||||
"""
|
||||
],
|
||||
transform: [
|
||||
type: {:or, [{:spark_function_behaviour, Step, {Step.TransformAll, 1}}, nil]},
|
||||
required: false,
|
||||
default: nil,
|
||||
doc: """
|
||||
An optional transformation function which can be used to modify the
|
||||
entire argument map before it is returned.
|
||||
"""
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
defimpl Dsl.Build do
|
||||
def build(collect, reactor) do
|
||||
Builder.add_step(
|
||||
reactor,
|
||||
collect.name,
|
||||
Step.ReturnAllArguments,
|
||||
collect.arguments,
|
||||
async?: true,
|
||||
max_retries: 1,
|
||||
transform: collect.transform,
|
||||
ref: :step_name
|
||||
)
|
||||
end
|
||||
|
||||
def verify(_collect, _dsl_state), do: :ok
|
||||
def transform(_collect, dsl_state), do: {:ok, dsl_state}
|
||||
end
|
||||
end
|
|
@ -66,7 +66,7 @@ defmodule Reactor.Dsl.Step do
|
|||
"""
|
||||
],
|
||||
args: [:name, {:optional, :impl}],
|
||||
target: Dsl.Step,
|
||||
target: __MODULE__,
|
||||
identifier: :name,
|
||||
no_depend_modules: [:impl],
|
||||
entities: [arguments: [Dsl.Argument.__entity__(), Dsl.WaitFor.__entity__()]],
|
||||
|
@ -79,7 +79,7 @@ defmodule Reactor.Dsl.Step do
|
|||
A unique name for the step.
|
||||
|
||||
This is used when choosing the return value of the Reactor and for arguments into
|
||||
another step.
|
||||
other steps.
|
||||
"""
|
||||
],
|
||||
impl: [
|
||||
|
|
39
test/reactor/dsl/collect_test.exs
Normal file
39
test/reactor/dsl/collect_test.exs
Normal file
|
@ -0,0 +1,39 @@
|
|||
defmodule Reactor.Dsl.CollectTest do
|
||||
@moduledoc false
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
defmodule Noop do
|
||||
@moduledoc false
|
||||
use Reactor.Step
|
||||
|
||||
def run(_, context, _), do: {:ok, context.current_step.name}
|
||||
end
|
||||
|
||||
defmodule CollectTransformReactor do
|
||||
@moduledoc false
|
||||
use Reactor
|
||||
|
||||
input :organisation
|
||||
input :repository
|
||||
|
||||
collect :latest_release_uri do
|
||||
argument :org, input(:organisation)
|
||||
argument :repo, input(:repository)
|
||||
transform &__MODULE__.do_transform/1
|
||||
end
|
||||
|
||||
def do_transform(inputs) do
|
||||
%{uri: "https://api.github.com/repos/#{inputs.org}/#{inputs.repo}/releases/latest"}
|
||||
end
|
||||
end
|
||||
|
||||
test "it works" do
|
||||
assert {:ok, result} =
|
||||
Reactor.run(CollectTransformReactor, %{
|
||||
organisation: "ash-project",
|
||||
repository: "reactor"
|
||||
})
|
||||
|
||||
assert result.uri == "https://api.github.com/repos/ash-project/reactor/releases/latest"
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue