Module: Axn::Mountable::MountingStrategies::Step

Extended by:
Step
Includes:
Base
Included in:
Step
Defined in:
lib/axn/mountable/mounting_strategies/step.rb

Defined Under Namespace

Modules: CallCollisionGuard, DSL

Constant Summary collapse

CALL_COLLISION_MESSAGE =
"%s declares steps and a custom #call. Steps generate the #call orchestrator, so you " \
"can't also define one. Use before/after hooks for setup/teardown around the steps."

Instance Method Summary collapse

Methods included from Base

#define_namespace_methods, #key, #mount, #mount_method, #mount_to_namespace, #preprocess_kwargs

Instance Method Details

#default_inherit_modeObject



13
# File 'lib/axn/mountable/mounting_strategies/step.rb', line 13

def default_inherit_mode = :none

#mount_to_target(descriptor:, target:) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/axn/mountable/mounting_strategies/step.rb', line 64

def mount_to_target(descriptor:, target:)
  # Ensure the mounted axn class is registered (e.g. as a constant under target's namespace)
  descriptor.mounted_axn_for(target:)

  # Only define #call method once
  return if target.instance_variable_defined?(:@_axn_call_method_defined_for_steps)

  # A user-authored #call already on this class (steps declared after `def call`) collides
  # with the orchestrator we're about to generate — fail at declaration (AGENTS.md). Check
  # private methods too: instance_methods(false) omits a `private def call`, which would
  # otherwise be silently replaced (the reverse order is caught by method_added, which fires
  # regardless of visibility).
  if (target.instance_methods(false) + target.private_instance_methods(false)).include?(:call)
    raise ArgumentError, format(CALL_COLLISION_MESSAGE, target.name || "Action")
  end

  _define_steps_call(target)
  _install_call_collision_guard(target)
  target.instance_variable_set(:@_axn_call_method_defined_for_steps, true)
end

#strategy_specific_kwargsObject



58
# File 'lib/axn/mountable/mounting_strategies/step.rb', line 58

def strategy_specific_kwargs = super + %i[error_prefix if unless]

#validate_conditions!(kwargs) ⇒ Object

if:/unless: must be a Symbol (a parent method) or a Proc-compatible callable — fail at declaration (AGENTS.md). Use the same callable? seam as the rest of the contract: it requires to_proc (which the runner's instance_exec(&condition) needs), so a bare #call-only object is rejected here rather than raising TypeError at run time.



47
48
49
50
51
52
53
54
55
56
# File 'lib/axn/mountable/mounting_strategies/step.rb', line 47

def validate_conditions!(kwargs)
  %i[if unless].each do |key|
    next unless kwargs.key?(key)

    condition = kwargs[key]
    next if condition.is_a?(Symbol) || ::Axn::Core::Flow::Handlers::Invoker.callable?(condition)

    raise ArgumentError, "step #{key}: must be a Symbol or callable (got #{condition.inspect})"
  end
end