lib/snfoil/context.rb in snfoil-context-0.0.2 vs lib/snfoil/context.rb in snfoil-context-0.0.4
- old
+ new
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-# Copyright 2021 Matthew Howes
+# Copyright 2021 Matthew Howes, Cliff Campbell
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
@@ -33,63 +33,67 @@
include SnFoil::Context::Structure
end
class_methods do
def action(name, with: nil, &block)
- raise SnFoil::Context::Error, "action #{name} already defined for #{self.name}" if (@defined_actions ||= []).include?(name)
+ raise SnFoil::Context::Error, "action #{name} already defined for #{self.name}" if (@snfoil_actions ||= []).include?(name)
- @defined_actions << name
- define_workflow_hooks(name)
+ @snfoil_actions << name
+ define_workflow(name)
define_action_primary(name, with, block)
end
- end
- def run_action_group(group_name, **options)
- hooks = self.class.instance_variable_get("@#{group_name}_hooks") || []
- options = hooks.reduce(options) { |opts, hook| run_hook(hook, opts) }
- options = send(group_name, **options) if respond_to?(group_name)
+ def interval(name)
+ define_singleton_methods(name)
+ define_instance_methods(name)
+ end
- options
+ def intervals(*names)
+ names.each { |name| interval(name) }
+ end
end
+ def run_interval(interval, **options)
+ hooks = self.class.instance_variable_get("@snfoil_#{interval}_hooks") || []
+ options = hooks.reduce(options) { |opts, hook| run_hook(hook, **opts) }
+ send(interval, **options)
+ end
+
private
# rubocop:disable reason: These are builder/mapping methods that are just too complex to simplify without
# making them more complex. If anyone has a better way please let me know
class_methods do # rubocop:disable Metrics/BlockLength
+ def define_workflow(name)
+ interval format('setup_%s', name)
+ interval format('before_%s', name)
+ interval format('after_%s_success', name)
+ interval format('after_%s_failure', name)
+ interval format('after_%s', name)
+ end
+
def define_action_primary(name, method, block) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
- define_method(name) do |**options| # rubocop:disable Metrics/MethodLength
- options[:action] = name.to_sym
- options = run_action_group(format('setup_%s', name), **options)
+ define_method(name) do |*_args, **options| # rubocop:disable Metrics/MethodLength
+ options[:action] ||= name.to_sym
+
+ options = run_interval(format('setup_%s', name), **options)
authorize(name, **options) if respond_to?(:authorize)
- options = run_action_group(format('before_%s', name), **options)
+ options = run_interval(format('before_%s', name), **options)
authorize(name, **options) if respond_to?(:authorize)
options = if run_action_primary(method, block, **options)
- run_action_group(format('after_%s_success', name), **options)
+ run_interval(format('after_%s_success', name), **options)
else
- run_action_group(format('after_%s_failure', name), **options)
+ run_interval(format('after_%s_failure', name), **options)
end
- run_action_group(format('after_%s', name), **options)
+ run_interval(format('after_%s', name), **options)
end
end
- def define_workflow_hooks(name)
- hook_builder('setup_%s', name)
- hook_builder('before_%s', name)
- hook_builder('after_%s_success', name)
- hook_builder('after_%s_failure', name)
- hook_builder('after_%s', name)
- end
-
- def hook_builder(name_format, name)
- assign_singleton_methods format(name_format, name),
- format("#{name_format}_hooks", name)
- end
-
- def assign_singleton_methods(method_name, singleton_var)
+ def define_singleton_methods(method_name)
+ singleton_var = "snfoil_#{method_name}_hooks"
instance_variable_set("@#{singleton_var}", [])
define_singleton_method(singleton_var) { instance_variable_get("@#{singleton_var}") }
define_singleton_method(method_name) do |method = nil, **options, &block|
raise SnFoil::Context::ArgumentError, "\##{method_name} requires either a method name or a block" if method.nil? && block.nil?
@@ -97,14 +101,20 @@
block: block,
if: options[:if],
unless: options[:unless] }
end
end
+
+ def define_instance_methods(method_name)
+ define_method(method_name) do |**options|
+ options
+ end
+ end
end
def run_action_primary(method, block, **options)
return send(method, **options) if method
- instance_exec options, &block
+ instance_exec(**options, &block)
end
end
end