blueprints 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +14 -1
  3. data/README.rdoc +3 -173
  4. data/Rakefile +32 -15
  5. data/blueprints.gemspec +2 -16
  6. data/lib/blueprints.rb +17 -10
  7. data/lib/blueprints/blueprint.rb +85 -41
  8. data/lib/blueprints/blueprint_name_proxy.rb +34 -0
  9. data/lib/blueprints/buildable.rb +53 -26
  10. data/lib/blueprints/context.rb +8 -0
  11. data/lib/blueprints/extensions.rb +22 -4
  12. data/lib/blueprints/extensions/rspec.rb +28 -14
  13. data/lib/blueprints/helper.rb +17 -9
  14. data/lib/blueprints/namespace.rb +20 -14
  15. data/lib/blueprints/railtie.rb +3 -0
  16. data/lib/blueprints/root_namespace.rb +16 -23
  17. data/lib/blueprints/version.rb +1 -1
  18. data/lib/generators/blueprints/model/model_generator.rb +29 -0
  19. data/spec/blueprints_spec.rb +18 -1
  20. data/spec/support/active_record/initializer.rb +9 -5
  21. data/spec/support/none/initializer.rb +4 -0
  22. data/spec/unit/active_record_spec.rb +58 -4
  23. data/spec/unit/blueprint_name_proxy_spec.rb +31 -0
  24. data/spec/unit/blueprint_spec.rb +160 -22
  25. data/spec/unit/blueprints_spec.rb +4 -4
  26. data/spec/unit/context_spec.rb +8 -1
  27. data/spec/unit/dependency_spec.rb +1 -5
  28. data/spec/unit/fixtures.rb +69 -47
  29. data/spec/unit/namespace_spec.rb +23 -5
  30. data/spec/unit/root_namespace_spec.rb +9 -0
  31. data/spec/unit/spec_helper.rb +3 -4
  32. data/test/blueprints_test.rb +18 -1
  33. data/test/test_helper.rb +1 -0
  34. data/test_all.sh +6 -33
  35. metadata +43 -276
  36. data/Gemfile.lock +0 -108
  37. data/lib/blueprints/database_cleaner_fix.rb +0 -9
  38. data/lib/blueprints/eval_context.rb +0 -51
  39. data/spec/unit/eval_context_spec.rb +0 -56
@@ -0,0 +1,34 @@
1
+ # Acts as a proxy to buildables with regexp names. Used for caching purposes. Remembers name used and always uses it later.
2
+ # Allows building and demolishing it's buildable.
3
+ class Blueprints::BlueprintNameProxy
4
+ # Initializes new instance of proxy.
5
+ # @param [Symbol] name Name of buildable that this proxy uses.
6
+ # @param [Blueprints::Buildable] buildable Buildable itself, that can later be built of demolished.
7
+ def initialize(name, buildable)
8
+ @buildable = buildable
9
+ @name = name
10
+
11
+ match_data = buildable.name.match(name.to_s)
12
+ names = match_data.names.collect(&:to_sym) if match_data.respond_to?(:names)
13
+ names = (0...match_data.captures.size).collect { |ind| :"arg#{ind}" } if names.blank?
14
+ @options = Hash[names.zip(match_data.captures)]
15
+ end
16
+
17
+ # Allows building buildable. Merges regexp match data into options. If named regexp captures are used (Ruby 1.9 only),
18
+ # it will merge those names with appropriate values into options, otherwise options will be named arg0..n.
19
+ # @param environment (see Buildable#build)
20
+ # @param options (see Buildable#build)
21
+ # @return (see Buildable#build)
22
+ def build(environment, options = {})
23
+ options[:options] ||= {}
24
+ options[:options].merge!(@options)
25
+ options.merge!(:name => @name)
26
+ @buildable.build(environment, options)
27
+ end
28
+
29
+ # Allows demolishing buildable. Uses remembered name to determine name of variable to call destroy on.
30
+ # @param [Object] environment Eval context that this buildable was built in.
31
+ def demolish(environment)
32
+ @buildable.demolish(environment, @name)
33
+ end
34
+ end
@@ -1,5 +1,7 @@
1
1
  module Blueprints
2
2
  class Buildable
3
+ BUILDING_MESSAGE = 'While building blueprint'
4
+
3
5
  delegate :namespace, :dependencies, :to => :@context
4
6
  attr_reader :name
5
7
 
@@ -11,10 +13,7 @@ module Blueprints
11
13
  def initialize(name, context)
12
14
  @context = context
13
15
 
14
- if name.nil?
15
- default_attribute = Blueprints.config.default_attributes.detect { |attribute| attributes.has_key?(attribute) }
16
- name = attributes[default_attribute].parameterize('_') if default_attribute
17
- end
16
+ name = self.class.infer_name(attributes) if name.nil?
18
17
  @name, parents = parse_name(name)
19
18
  depends_on(*parents)
20
19
 
@@ -47,22 +46,28 @@ module Blueprints
47
46
  end
48
47
  end
49
48
 
50
- # Builds dependencies of blueprint and then blueprint itself.
51
- # @param [Blueprints::EvalContext] eval_context Context to build buildable object in.
52
- # @param [true, false] build_once Used if buildable is already built. If true then old one is updated else buildable is built again.
53
- # @param [Hash] options List of options to be accessible in the body of a blueprint.
54
- def build(eval_context, build_once = true, options = {})
55
- return result(eval_context) if @building or (built? and build_once and options.blank?)
49
+ # Builds dependencies of buildable and then buildable itself.
50
+ # @param [Object] environment Context to build buildable object in.
51
+ # @param [Hash] options List of options to build this buildable with.
52
+ # @option options [Hash] :options ({}) List of options to be accessible in the body of a blueprint.
53
+ # @option options [true, false] :rebuild (false) If true this buildable is treated as not built yet and is rebuilt even if it was built before.
54
+ # @option options [Symbol] :strategy (:default) Strategy to use when building.
55
+ # @option options [Symbol] :name Name of blueprint to use when building. Is usually passed for blueprints with regexp names.
56
+ def build(environment, options = {})
57
+ return result(environment) if @building or (built? and not options[:rebuild] and options[:options].blank?)
56
58
  @building = true
57
59
 
58
- each_namespace { |namespace| namespace.build_parents(eval_context) }
59
- build_parents(eval_context)
60
-
61
- result = build_self(eval_context, build_once, options)
60
+ result = nil
61
+ surface_errors do
62
+ each_namespace { |namespace| namespace.build_parents(environment) }
63
+ build_parents(environment)
64
+ result = build_self(environment, options)
65
+ end
62
66
  Namespace.root.executed_blueprints << self
63
67
 
64
- @building = false
65
68
  result
69
+ ensure
70
+ @building = false
66
71
  end
67
72
 
68
73
  # Returns if blueprint has been built
@@ -78,9 +83,12 @@ module Blueprints
78
83
 
79
84
  # Returns full path to this buildable
80
85
  # @param [String] join_with Separator used to join names of parent namespaces and buildable itself.
86
+ # @param [#to_s] current_name Current name of this buildable. Used for regexp named buildables. Defaults to @name.
81
87
  # @return [String] full path to this buildable joined with separator
82
- def path(join_with = '_')
83
- (namespace.path(join_with) + join_with unless namespace.nil? or namespace.path.empty?).to_s + @name.to_s
88
+ def path(join_with = '_', current_name = nil)
89
+ current_name ||= @name
90
+ namespace_path = namespace.path(join_with) if namespace
91
+ [namespace_path.presence, current_name].compact.join(join_with)
84
92
  end
85
93
 
86
94
  # Returns full name for this buildable
@@ -90,9 +98,9 @@ module Blueprints
90
98
  end
91
99
 
92
100
  # Builds all dependencies. Should be called before building itself. Searches dependencies first in parent then in root namespace.
93
- # @param [Blueprints::EvalContext] eval_context Context to build parents against.
101
+ # @param [Object] environment Context to build parents against.
94
102
  # @raise [Blueprints::BlueprintNotFoundError] If one of dependencies can't be found.
95
- def build_parents(eval_context)
103
+ def build_parents(environment)
96
104
  @context.dependencies.each do |name|
97
105
  parent = begin
98
106
  namespace[name]
@@ -100,10 +108,18 @@ module Blueprints
100
108
  Namespace.root[name]
101
109
  end
102
110
 
103
- parent.build(eval_context)
111
+ parent.build(environment)
104
112
  end
105
113
  end
106
114
 
115
+ # Infers name of buildable using default attributes from Blueprints.config
116
+ # @param [Hash] attributes Attributes of buildable object to infer the name from.
117
+ # @return [String] Inferred name
118
+ def self.infer_name(attributes)
119
+ default_attribute = Blueprints.config.default_attributes.detect { |attribute| attributes.has_key?(attribute) }
120
+ attributes[default_attribute].parameterize('_') if default_attribute
121
+ end
122
+
107
123
  protected
108
124
 
109
125
  def each_namespace
@@ -111,8 +127,8 @@ module Blueprints
111
127
  yield(namespace) while namespace = namespace.namespace
112
128
  end
113
129
 
114
- def variable_name
115
- :"@#{path}"
130
+ def variable_name(current_name = nil)
131
+ :"@#{path('_', current_name || @name)}"
116
132
  end
117
133
 
118
134
  def parse_name(name)
@@ -121,6 +137,8 @@ module Blueprints
121
137
  elsif name.respond_to?(:to_sym)
122
138
  name = name.to_sym unless name == ''
123
139
  return name, []
140
+ elsif name.is_a? Regexp
141
+ return name, []
124
142
  else
125
143
  raise TypeError, "Pass blueprint names as strings or symbols only, cannot define blueprint #{name.inspect}"
126
144
  end
@@ -133,17 +151,26 @@ module Blueprints
133
151
 
134
152
  private
135
153
 
136
- def result(eval_context)
154
+ def result(environment, current_name = nil)
155
+ variable_name = self.variable_name(current_name)
137
156
  if block_given?
138
157
  yield.tap do |result|
139
- if @auto_variable or not eval_context.instance_variable_defined?(variable_name)
140
- eval_context.instance_variable_set(variable_name, result)
158
+ if @auto_variable or not environment.instance_variable_defined?(variable_name)
159
+ environment.instance_variable_set(variable_name, result)
141
160
  @auto_variable = true
142
161
  end
143
162
  end
144
163
  else
145
- eval_context.instance_variable_get(variable_name)
164
+ environment.instance_variable_get(variable_name)
146
165
  end
147
166
  end
167
+
168
+ def surface_errors
169
+ yield
170
+ rescue StandardError => error
171
+ insert_at = error.backtrace.index { |line| line !~ /^#{BUILDING_MESSAGE}/ }
172
+ error.backtrace.insert(insert_at, "#{BUILDING_MESSAGE} '#{path}'")
173
+ raise
174
+ end
148
175
  end
149
176
  end
@@ -133,6 +133,14 @@ module Blueprints
133
133
  Dependency.new(*args)
134
134
  end
135
135
 
136
+ # Finds blueprint/namespace by it's path
137
+ # @param path (see Namespace#[])
138
+ # @return (see Namespace#[])
139
+ def find(path)
140
+ @namespace[path]
141
+ end
142
+ alias [] find
143
+
136
144
  # Return current context.
137
145
  # @return [Blueprints::Context] Current context.
138
146
  def self.current
@@ -33,7 +33,7 @@ module Blueprints::Extensions
33
33
  def blueprint(*args)
34
34
  if Blueprints::Context.current
35
35
  attrs = args.extract_options!
36
- define_blueprint(args.first, attrs)
36
+ define_blueprint(args.first || Blueprints::Buildable.infer_name(attrs) || name.underscore, attrs)
37
37
  else
38
38
  objects = args.collect { |attrs| blueprint_object(attrs) }
39
39
  args.size == 1 ? objects.first : objects
@@ -44,7 +44,11 @@ module Blueprints::Extensions
44
44
 
45
45
  def define_blueprint(name, attrs)
46
46
  klass = self
47
- Blueprints::Context.current.attributes(attrs).blueprint(name) { klass.blueprint attributes }
47
+ Blueprints::Context.current.attributes(attrs).blueprint(name) do
48
+ klass.blueprint attributes
49
+ end.blueprint(:new) do
50
+ klass.new.tap { |object| object.blueprint_without_save(attributes) }
51
+ end
48
52
  end
49
53
 
50
54
  def blueprint_object(attrs)
@@ -59,6 +63,7 @@ module Blueprints::Extensions
59
63
  blueprint_attribute attribute, value
60
64
  end
61
65
  end
66
+ alias blueprint_without_save blueprint
62
67
 
63
68
  private
64
69
 
@@ -109,7 +114,20 @@ module Blueprints::Extensions
109
114
  end
110
115
  end
111
116
 
112
- ActiveRecord::Base.send(:include, Blueprints::Extensions::Saveable) if defined?(ActiveRecord)
117
+ if defined?(ActiveRecord)
118
+ ActiveRecord::Base.send(:include, Blueprints::Extensions::Saveable)
119
+ # AssociationCollection for ActiveRecord 3.0, Collection::Association for ActiveRecord 3.1
120
+ collection_class = defined?(ActiveRecord::Associations::CollectionProxy) ? ActiveRecord::Associations::CollectionProxy : ActiveRecord::Associations::AssociationCollection
121
+ collection_class.class_eval do
122
+ include Blueprints::Extensions::Blueprintable::ClassMethods
123
+
124
+ def blueprint_object(attrs)
125
+ create! do |object|
126
+ object.blueprint_without_save(attrs)
127
+ end
128
+ end
129
+ end
130
+ end
113
131
  Mongoid::Document.send(:include, Blueprints::Extensions::DynamicSaveable) if defined?(Mongoid)
114
- MongoMapper::Document.send(:append_inclusions, Blueprints::Extensions::DynamicSaveable) if defined?(MongoMapper)
132
+ MongoMapper::Document.send(:plugin, Blueprints::Extensions::DynamicSaveable) if defined?(MongoMapper)
115
133
  DataMapper::Model.send(:append_inclusions, Blueprints::Extensions::SoftSaveable) if defined?(DataMapper)
@@ -1,24 +1,38 @@
1
- module DescribeHelper
2
- # Creates new before filter that builds blueprints before each spec.
3
- # @param names (see Helper#build)
4
- def build_blueprint(*names)
5
- before { build_blueprint *names }
6
- end
1
+ module Blueprints
2
+ module DescribeHelper
3
+ # Creates new before filter that builds blueprints before each spec.
4
+ # @param names (see Helper#build)
5
+ def build_blueprint(*names)
6
+ before { build_blueprint *names }
7
+ end
7
8
 
8
- # Same as DescribeHelper#build_blueprint except that you can use it to build same blueprint several times.
9
- # @param names (see Helper#build)
10
- def build_blueprint!(*names)
11
- before { build_blueprint! *names }
12
- end
9
+ # Same as DescribeHelper#build_blueprint except that you can use it to build same blueprint several times.
10
+ # @param names (see Helper#build)
11
+ def build_blueprint!(*names)
12
+ before { build_blueprint! *names }
13
+ end
13
14
 
14
- alias :build :build_blueprint
15
- alias :build! :build_blueprint!
15
+ # Returns Blueprint::Dependency object that can be used to define dependencies on other blueprints.
16
+ # @example Building :post blueprint with different user.
17
+ # build :post => {:user => d(:admin)}
18
+ # @example Building :post blueprint by first building :user_profile with :name => 'John', then taking value of @profile and calling +user+ on it.
19
+ # build :post => {:user => d(:user_profile, :profile, :name => 'John').user}
20
+ # @see Blueprints::Dependency#initialize Blueprints::Dependency for accepted arguments.
21
+ # @return [Blueprints::Dependency] Dependency object that can be passed as option when building blueprint/namespace.
22
+ def d(*args)
23
+ Dependency.new(*args)
24
+ end
25
+
26
+ alias :build :build_blueprint
27
+ alias :blueprint_dependency :d
28
+ alias :build! :build_blueprint!
29
+ end
16
30
  end
17
31
 
18
32
  config_class = defined?(RSpec) ? RSpec : Spec::Runner
19
33
  config_class.configure do |config|
20
34
  config.include(Blueprints::Helper)
21
- config.extend(DescribeHelper)
35
+ config.extend(Blueprints::DescribeHelper)
22
36
  config.before do
23
37
  Blueprints.setup(self)
24
38
  end
@@ -12,25 +12,33 @@ module Blueprints
12
12
  # @param [Array<Symbol, String, Hash>] names Names of blueprints/namespaces to build. Pass Hash if you want to pass additional options.
13
13
  # @return Return value of last blueprint
14
14
  def build(*names)
15
- Namespace.root.build(names, self, true)
15
+ Namespace.root.build(names, self)
16
16
  end
17
17
 
18
- # Same as #build except that you can use it to build same blueprint several times.
18
+ # Same as Blueprints::Helper#build except that you can use it to build same blueprint several times.
19
19
  # @overload build!(*names)
20
- # @param [Array<Symbol, String, Hash>] names Names of blueprints/namespaces to build. Pass Hash if you want to pass additional options.
21
- # @return Return value of last blueprint
20
+ # @param names (see Helper#build)
21
+ # @return (see Helper#build)
22
22
  # @overload build!(count, *names)
23
23
  # @param [Integer] count Times to build passed blueprint
24
- # @param [Array<Symbol, String, Hash>] names Names of blueprints/namespaces to build. Pass Hash if you want to pass additional options.
24
+ # @param names (see Helper#build)
25
25
  # @return [Array] Array of return values of last blueprint, which is same size as count that you pass
26
26
  def build!(*names)
27
27
  if names.first.is_a?(Integer)
28
28
  (0...names.shift).collect { build! *names }
29
29
  else
30
- Namespace.root.build(names, self, false)
30
+ Namespace.root.build(names, self, :rebuild => true)
31
31
  end
32
32
  end
33
33
 
34
+ # Same as Blueprints::Helper#build except it also allows you to pass strategy to use (#build always uses default strategy).
35
+ # @param [Symbol] strategy Strategy to use when building blueprint/namespace.
36
+ # @param names (see Helper#build)
37
+ # @return (see Helper#build)
38
+ def build_with(strategy, *names)
39
+ Namespace.root.build(names, self, :strategy => strategy)
40
+ end
41
+
34
42
  # Returns attributes that are used to build blueprint.
35
43
  # @example Setting and retrieving attributes.
36
44
  # # In blueprint.rb file
@@ -44,8 +52,8 @@ module Blueprints
44
52
  # @return [Hash] Normalized attributes of blueprint/namespace
45
53
  def build_attributes(name)
46
54
  blueprint = Namespace.root[name]
47
- blueprint.build_parents(Namespace.root.eval_context)
48
- Namespace.root.eval_context.normalize_hash(blueprint.attributes).tap { Namespace.root.eval_context.copy_instance_variables(self) }
55
+ blueprint.build_parents(self)
56
+ blueprint.normalized_attributes(self)
49
57
  end
50
58
 
51
59
  # Returns Blueprint::Dependency object that can be used to define dependencies on other blueprints.
@@ -64,7 +72,7 @@ module Blueprints
64
72
  # demolish :apple, :pear
65
73
  # @param [Array<Symbol, String>] names Names of blueprints/namespaces to demolish.
66
74
  def demolish(*names)
67
- names.each { |name| Namespace.root[name].demolish(Namespace.root.eval_context) }
75
+ names.each { |name| Namespace.root[name].demolish(self) }
68
76
  end
69
77
 
70
78
  alias :build_blueprint :build
@@ -3,14 +3,18 @@ module Blueprints
3
3
  # all it's children.
4
4
  class Namespace < Buildable
5
5
  cattr_accessor :root
6
- attr_reader :children
7
6
  delegate :empty?, :size, :to => :@children
8
7
 
9
8
  # Creates namespace by name. See Buildable#new.
10
9
  # @param name (see Buildable#initialize)
11
10
  # @param context (see Buildable#initialize)
12
11
  def initialize(name, context)
13
- @children = {}
12
+ @children = Hash.new do |hash, search_key|
13
+ pair = hash.detect do |name,|
14
+ name.is_a?(Regexp) and search_key.to_s =~ name
15
+ end
16
+ hash[search_key] = BlueprintNameProxy.new(search_key, pair[1]) if pair
17
+ end
14
18
  super(name, context)
15
19
  end
16
20
 
@@ -21,6 +25,12 @@ module Blueprints
21
25
  @children[child.name] = child
22
26
  end
23
27
 
28
+ # Returns all direct children blueprints and namespaces of this namespace.
29
+ # @return [Array<Blueprints::Buildable>] Array of direct children
30
+ def children
31
+ @children.values
32
+ end
33
+
24
34
  # Finds child by relative name.
25
35
  # @param [String] path Path to child. Path parts should be joined with '.' symbol.
26
36
  # @return [Blueprints::Buildable] Blueprint or namespace that matches path.
@@ -36,23 +46,19 @@ module Blueprints
36
46
  end
37
47
  end
38
48
 
39
- # Builds all children and sets an instance variable named by name of namespace with the results.
40
- # @param eval_context (see Buildable#build)
41
- # @param build_once (see Buildable#build)
42
- # @param options (see Buildable#build)
43
- # @return [Array] Results of all blueprints.
44
- def build_self(eval_context, build_once, options)
45
- result(eval_context) { @children.values.collect { |child| child.build(eval_context, build_once, options) }.uniq }
46
- end
47
-
48
49
  # Demolishes all child blueprints and namespaces.
49
- # @param [Blueprints::EvalContext] eval_context Eval context that this namespace was built in.
50
- def demolish(eval_context)
51
- @children.each_value { |blueprint| blueprint.demolish(eval_context) }
50
+ # @param [Object] environment Eval context that this namespace was built in.
51
+ def demolish(environment)
52
+ @children.each_value { |blueprint| blueprint.demolish(environment) }
52
53
  end
53
54
 
54
55
  protected
55
56
 
57
+ def build_self(environment, options)
58
+ children = Array(@children[:default] || @children.values)
59
+ result(environment) { children.collect { |child| child.build(environment, options) } }
60
+ end
61
+
56
62
  def update_context(options)
57
63
  @children.each_value { |child| child.update_context(options) }
58
64
  super
@@ -0,0 +1,3 @@
1
+ class Blueprints::Railtie < Rails::Railtie
2
+ config.app_generators.fixture_replacement :blueprints
3
+ end
@@ -6,8 +6,6 @@ module Blueprints
6
6
  class RootNamespace < Namespace
7
7
  # Lists of executed blueprints (to prevent executing twice). Cleared before each test.
8
8
  attr_reader :executed_blueprints
9
- # Context that blueprints/namespaces are built against. Reset before each test.
10
- attr_writer :eval_context
11
9
 
12
10
  # Initialized new root context.
13
11
  def initialize
@@ -17,53 +15,48 @@ module Blueprints
17
15
  super '', Context.new
18
16
  end
19
17
 
20
- # Loads all instance variables from global context to current one. Creates new eval context.
21
- def setup
22
- @eval_context = EvalContext.new
18
+ # Loads all instance variables from global context to current one.
19
+ def setup(environment)
23
20
  (@executed_blueprints - @global_executed_blueprints).each(&:undo!)
24
21
  @executed_blueprints = @global_executed_blueprints.clone
25
22
 
26
23
  if Blueprints.config.transactions
27
- Marshal.load(@global_variables).each { |name, value| eval_context.instance_variable_set(name, value) }
24
+ Marshal.load(@global_variables).each { |name, value| environment.instance_variable_set(name, value) }
28
25
  else
29
- build(Blueprints.config.prebuild)
26
+ build(Blueprints.config.prebuild, environment)
30
27
  end
31
28
  end
32
29
 
33
- # Sets up global context and executes prebuilt blueprints against it.
30
+ # Sets up a context and executes prebuilt blueprints against it.
34
31
  # @param [Array<Symbol, String>] blueprints Names of blueprints that are prebuilt.
35
32
  def prebuild(blueprints)
36
- build(blueprints) if blueprints
33
+ environment = Object.new
34
+ environment.extend Blueprints::Helper
35
+ build(blueprints, environment) if blueprints
37
36
 
38
37
  @global_executed_blueprints = @executed_blueprints
39
- @global_variables = Marshal.dump(eval_context.instance_variables.each_with_object({}) { |iv, hash| hash[iv] = eval_context.instance_variable_get(iv) })
38
+ @global_variables = Marshal.dump(environment.instance_variables.each_with_object({}) { |iv, hash| hash[iv] = environment.instance_variable_get(iv) })
40
39
  end
41
40
 
42
- # Builds blueprints that are passed against current context. Copies instance variables to context given if one is given.
41
+ # Builds blueprints that are passed against current context.
43
42
  # @param [Array<Symbol, String>] names List of blueprints/namespaces to build.
44
- # @param current_context Object to copy instance variables from eval context after building to.
45
- # @param build_once (see Buildable.build)
43
+ # @param environment Object to build blueprints against.
44
+ # @param options (see Buildable#build)
45
+ # @option options (see Buildable#build)
46
46
  # @return Result of last blueprint/namespace.
47
- def build(names, current_context = nil, build_once = true)
47
+ def build(names, environment, options = {})
48
48
  names = [names] unless names.is_a?(Array)
49
49
  result = names.inject(nil) do |result, member|
50
50
  if member.is_a?(Hash)
51
- member.map { |name, options| self[name].build(eval_context, build_once, options) }.last
51
+ member.map { |name, opts| self[name].build(environment, options.merge(:options => opts)) }.last
52
52
  else
53
- self[member].build(eval_context, build_once)
53
+ self[member].build(environment, options)
54
54
  end
55
55
  end
56
56
 
57
- eval_context.copy_instance_variables(current_context) if current_context
58
57
  result
59
58
  end
60
59
 
61
- # Return current eval context or creates a new one.
62
- # @return [Blueprints::EvalContext] Eval context to be used to build blueprints.
63
- def eval_context
64
- @eval_context ||= EvalContext.new
65
- end
66
-
67
60
  @@root = RootNamespace.new
68
61
  end
69
62
  end