refactor the most complex thing in the app, in preparation of more cleaning

This commit is contained in:
John Bintz 2012-10-09 14:33:12 -04:00
parent 0ba33a008d
commit 9e9ce113cd
10 changed files with 119 additions and 36 deletions

View File

@ -263,6 +263,7 @@ Feature: Gemfiles
gem "two", {:require=>nil} gem "two", {:require=>nil}
""" """
@wip
Scenario: Set the opposite environment in the environment defaults Scenario: Set the opposite environment in the environment defaults
Given I have the file "Gemfile.penchant" with the content: Given I have the file "Gemfile.penchant" with the content:
""" """

View File

@ -7,4 +7,9 @@ module Penchant
autoload :FileProcessor, 'penchant/file_processor' autoload :FileProcessor, 'penchant/file_processor'
autoload :PenchantFile, 'penchant/penchant_file' autoload :PenchantFile, 'penchant/penchant_file'
autoload :Defaults, 'penchant/defaults' autoload :Defaults, 'penchant/defaults'
autoload :Properties, 'penchant/properties'
autoload :CustomProperty, 'penchant/custom_property'
autoload :PropertyStack, 'penchant/property_stack'
autoload :PropertyStackBuilder, 'penchant/property_stack_builder'
autoload :PropertyStackProcessor, 'penchant/property_stack_processor'
end end

View File

@ -0,0 +1,20 @@
module Penchant
class CustomProperty
def initialize(value)
@value = value
end
def process(values)
if @value.respond_to?(:call)
@value.call(*values).to_a
else
@value.collect do |k, v|
v = v.dup.gsub(%r{\$(\d+)}) { |m| values[m.to_i - 1 ] }
[ k, v ]
end
end
end
end
end

View File

@ -21,7 +21,7 @@ module Penchant
@available_environments = [] @available_environments = []
@defined_git_repos = [] @defined_git_repos = []
@defaults = Defaults.new @defaults = Defaults.new
@properties = {} @properties = PropertyStackBuilder.new(@defaults)
@_current_env_defaults = {} @_current_env_defaults = {}
end end
@ -131,9 +131,7 @@ module Penchant
end end
def process_options(gem_name, template = {}) def process_options(gem_name, template = {})
properties = {} properties = Properties.new(template)
property_stack = template.to_a
original_properties = process_option_stack(gem_name, property_stack) original_properties = process_option_stack(gem_name, property_stack)
@ -148,36 +146,6 @@ module Penchant
Hash[properties.sort] Hash[properties.sort]
end end
def process_option_stack(gem_name, stack)
property_stack = stack.dup
properties = {}
while !property_stack.empty?
key, value = property_stack.shift
if property = @properties[key]
values = [ value ].flatten
if property.respond_to?(:call)
property.call(*values).each do |k, v|
property_stack.push([ k, v ])
end
else
property.each do |k, v|
v = v.dup.gsub(%r{\$(\d+)}) { |m| values[m.to_i - 1 ] }
property_stack.push([ k, v ])
end
end
else
value = value % gem_name if value.respond_to?(:%)
properties[key] = value
end
end
properties
end
def _defaults_for(gem_name) def _defaults_for(gem_name)
result = @_current_env_defaults result = @_current_env_defaults
result.merge(@defaults[gem_name] || {}) result.merge(@defaults[gem_name] || {})

View File

@ -14,7 +14,7 @@ module Penchant
version = args.first version = args.first
options = process_options(gem_name.first, template) options = @properties.create_stack_for(template, @_strip_pathing_options).process_for_gem(gem_name.first, @_current_env_defaults)
args = [ gem_name.first ] args = [ gem_name.first ]
args << version if version args << version if version
@ -36,7 +36,7 @@ module Penchant
gems, template = split_args(args) gems, template = split_args(args)
gems.flatten.each do |gem_name| gems.flatten.each do |gem_name|
options = process_options(gem_name, template) options = @properties.create_stack_for(template, @_strip_pathing_options).process_for_gem(gem_name)
args = [ gem_name ] args = [ gem_name ]
args << options if !options.empty? args << options if !options.empty?

View File

@ -0,0 +1,14 @@
module Penchant
class Properties
def initialize(template)
@properties = {}
@template = template.to_a
end
def process
end
end
end

0
lib/penchant/property.rb Normal file
View File

View File

@ -0,0 +1,26 @@
module Penchant
class PropertyStack
def initialize(builder, property_stack, strip_pathing_options)
@builder, @property_stack, @strip_pathing_options = builder, property_stack.dup, strip_pathing_options
end
def processor
@processor ||= PropertyStackProcessor.new(@builder)
end
def process_for_gem(gem_name, additional_env = {})
properties = processor.process(gem_name, @property_stack)
if @strip_pathing_options
[ :git, :branch, :path ].each { |key| properties.delete(key) }
end
properties = processor.process(gem_name, @builder.defaults[gem_name].merge(additional_env)).merge(properties)
properties.delete(:opposite)
Hash[properties.sort]
end
end
end

View File

@ -0,0 +1,23 @@
module Penchant
class PropertyStackBuilder
attr_reader :defaults
def initialize(defaults)
@defaults = defaults
@custom_properties = {}
end
def []=(key, value)
@custom_properties[key] = CustomProperty.new(value)
end
def [](key)
@custom_properties[key]
end
def create_stack_for(stack, strip_pathing_options = false)
PropertyStack.new(self, stack, strip_pathing_options)
end
end
end

View File

@ -0,0 +1,26 @@
module Penchant
class PropertyStackProcessor
def initialize(builder)
@builder = builder
end
def process(gem_name, stack)
properties = {}
property_stack = stack.dup.to_a
while !property_stack.empty?
key, value = property_stack.shift
if property = @builder[key]
property_stack += property.process([ value ].flatten)
else
value = value % gem_name if value.respond_to?(:%)
properties[key] = value
end
end
properties
end
end
end