Class: Rubuild::Build::Simple::Dep

Inherits:
Object
  • Object
show all
Defined in:
lib/rubuild/build/simple/dep.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command, name) ⇒ Dep

Returns a new instance of Dep.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/rubuild/build/simple/dep.rb', line 33

def initialize(command, name)
  self.rubuild_build_simple_dep__build_wait = 0
  self.rubuild_build_simple_dep__parents = Hash.new
  self.rubuild_build_simple_dep__children = Array.new
  self.rubuild_build_simple_dep__runable = false
  self.rubuild_build_simple_dep__built = false
  self.rubuild_build_simple_dep__loaded = Hash.new
  self.rubuild_build_simple_dep__circlecheck = false
  
  self.rubuild_build_simple_dep__command = command
  self.rubuild_build_simple_dep__name = name
  self.rubuild_build_simple_dep__err = nil
  self.args = []
end

Class Method Details



358
359
360
361
362
363
# File 'lib/rubuild/build/simple/dep.rb', line 358

def self.print_tree(file, tree, indent = 0)
  tree.keys.sort.each do |node|
    file.puts(' '*indent + node)
    self.print_tree(file, tree[node], indent+1)
  end
end

Instance Method Details

#action_error(err, runctx) ⇒ Object

Error err occurred while executing self‘s dependency command. Inform all child dependencies of the event. Used internally.

err

Exception that prevented self‘s dependency command from completing.

runctx

Rubuild::Build::Context used to execute self.

return

Rubuild::Build::Dep::Error::Action for err.



253
254
255
256
257
# File 'lib/rubuild/build/simple/dep.rb', line 253

def action_error(err, runctx)
  self.action_error_real(
    Rubuild::Build::Dep::Error::Action.new(self, err, runctx)
    )
end

#action_error_real(err) ⇒ Object

Inform all children that a parent dependency (or self) failed to execute a command due to err. Used internally.

err

Exception that prevents self from completing.

return

Rubuild::Build::Dep::Error::Action for err.



238
239
240
241
242
243
244
# File 'lib/rubuild/build/simple/dep.rb', line 238

def action_error_real(err)
  self.rubuild_build_simple_dep__err = err
  self.rubuild_build_simple_dep__children.each do |child|
    child.parent_action_error(self, err)
  end
  self.rubuild_build_simple_dep__err
end

#add_parent(dep) ⇒ Object

Makes dep a parent dependency of self - in other words, dep must be run before self can be run.

dep

Dependency that must be executed before self can execute.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/rubuild/build/simple/dep.rb', line 101

def add_parent(dep)
  if self.rubuild_build_simple_dep__runable
    raise Rubuild::Build::Dep::Error::Runable.new(self, dep)
  end
  # Are we already waiting for this dependency?
  if ! self.rubuild_build_simple_dep__parents.has_key?(dep)
    # No, so we probably want to add him in...
    # check that we're not creating a circular dependency.
    self.circle_check(Array.new, [dep])

    # Indicate that we want to block on parent...
    self.rubuild_build_simple_dep__build_wait += 1
    self.rubuild_build_simple_dep__parents[dep] = true
    # ...and tell parent to prod us after he runs.
    dep.child_added(self)
  end
  # The new parent will need to be loaded into any build context into
  # which self is loaded.
  self.rubuild_build_simple_dep__loaded.each_key do |bctx|
    dep.load(bctx)
  end
end

#args=(nargs) ⇒ Object

Sets the list of optional arguments with which the dependency action will be invoked.

nargs

New arguments to dependency action.

return

self.



63
64
65
66
67
68
69
# File 'lib/rubuild/build/simple/dep.rb', line 63

def args=(nargs)
  if self.rubuild_build_simple_dep__runable or self.rubuild_build_simple_dep__built
    raise Rubuild::Build::Dep::Error::Parameter::Args.new(self)
  end
  self.rubuild_build_simple_dep__args = nargs
  self
end

#buildersObject

Return array of all Rubuild::Build::Context objects that will build this dependency.



219
220
221
# File 'lib/rubuild/build/simple/dep.rb', line 219

def builders
  self.rubuild_build_simple_dep__loaded.keys
end

#child_added(dep) ⇒ Object

Record that a child dependency has been added to self. Used internally.

dep

New child dependency.



127
128
129
130
131
132
133
# File 'lib/rubuild/build/simple/dep.rb', line 127

def child_added(dep)
  if self.built
    dep.parent_built(self)
  else
    self.rubuild_build_simple_dep__children << dep
  end
end

#child_treeObject



348
349
350
351
352
353
354
355
356
# File 'lib/rubuild/build/simple/dep.rb', line 348

def child_tree
  rval = Hash.new
  if self.rubuild_build_simple_dep__children
    self.rubuild_build_simple_dep__children.each do |child|
      rval[child.name] = child.child_tree
    end
  end
  rval
end

#circle_check(loading, check) ⇒ Object

Check for circular dependencies. Used internally.

loading

Rubuild::Build::Dep chain in progress. Used as a backtrace, in case a circular dependency is detected.

check

Array of Rubuild::Build::Dep objects to place in ‘parent’ list, when searching for circular dependencies.



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/rubuild/build/simple/dep.rb', line 153

def circle_check(loading, check)
  if self.rubuild_build_simple_dep__circlecheck
    raise Rubuild::Build::Dep::Error::Load.new(self, loading)
  end
  if self.built
    return
  end
  self.rubuild_build_simple_dep__circlecheck = true
  parentcheck = check.dup
  if self.rubuild_build_simple_dep__parents
    self.rubuild_build_simple_dep__parents.each_pair do |key, value|
      if value
        parentcheck << key
      end
    end
  end
  pcheck_arr = Array.new
  loading.push(self)
  parentcheck.each do |parent|
    parent.circle_check(loading, pcheck_arr)
  end
  loading.pop
  self.rubuild_build_simple_dep__circlecheck = false
end

#load(buildctx) ⇒ Object

Loads self and all parent dependancies into the execution context buildctx.

buildctx

Rubuild::Build::Context into which self is being loaded.



213
214
215
# File 'lib/rubuild/build/simple/dep.rb', line 213

def load(buildctx)
  self.load_self(Array.new, buildctx)
end

#load_self(loading, buildctx) ⇒ Object

Record that a build-context is waiting to build this dependency. Search for circular dependencies. Used internally.

loading

Rubuild::Build::Dep dependency chain in progress, that lead to self being loaded into a Rubuild::Build::Context.

buildctx

Rubuild::Build::Context into which self is being loaded.



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/rubuild/build/simple/dep.rb', line 184

def load_self(loading, buildctx)
  if self.built
    return
  end
  if buildctx.dep_loaded(self) == true
    self.rubuild_build_simple_dep__loaded[buildctx] = loading.dup
    if self.rubuild_build_simple_dep__build_wait > 0
      parentcheck = Array.new
      self.rubuild_build_simple_dep__parents.each_pair do |key, value|
        if value
          parentcheck << key
        end
      end
      loading.push(self)
      parentcheck.each do |parent|
        parent.load_self(loading, buildctx)
      end
      loading.pop
    elsif self.rubuild_build_simple_dep__runable
      buildctx.dep_runable(self)
    else
      self.make_runable
    end
  end
end

#loaders(builder) ⇒ Object

Return the child-dependencies of self that placed self into the Rubuild::Build::Context builder.

builder

A Rubuild::Build::Context into which self was loaded.

return

The dependency hierarchy in builder that resulted in self being loaded, or nil if self was not loaded into builder.



229
230
231
# File 'lib/rubuild/build/simple/dep.rb', line 229

def loaders(builder)
  self.rubuild_build_simple_dep__loaded[builder]
end

#make_runableObject

Mark that all parent dependencies have been satisfied for self. Inform all build contexts that might execute this dependency that this dependency is now runable. Used internally.



139
140
141
142
143
144
145
# File 'lib/rubuild/build/simple/dep.rb', line 139

def make_runable
  self.rubuild_build_simple_dep__loaded.each_key do |buildctx|
    buildctx.dep_runable(self)
  end
  self.rubuild_build_simple_dep__runable = true
  self.rubuild_build_simple_dep__parents = nil
end

#nameObject

Returns a human-readable string describing the depandancy object, as set during initialization.

return

Human-readable string description of self dependency.



51
52
53
54
55
56
57
# File 'lib/rubuild/build/simple/dep.rb', line 51

def name
  if self.rubuild_build_simple_dep__name
    self.rubuild_build_simple_dep__name
  else
    super
  end
end

#parent_action_error(parent, err) ⇒ Object

Child is being informed by parent that error err occurred processing a dependency action. Used internally.

parent

Parent dependency that will not run, thus preventing self from running.

err

Error that prevents parent from running.



265
266
267
# File 'lib/rubuild/build/simple/dep.rb', line 265

def parent_action_error(parent, err)
  self.action_error_real(err)
end

#parent_built(dep) ⇒ Object

Record that a parent dependency has been built. Will result in this dependency being made runable, when all parent dependencies are satisfied. Used internally.

dep

Parent dependency that was built.



325
326
327
328
329
330
331
332
333
334
# File 'lib/rubuild/build/simple/dep.rb', line 325

def parent_built(dep)
  if ! self.rubuild_build_simple_dep__parents[dep]
    raise(Rubuild::Build::Dep::Error::DepInconsistent.new(self, dep))
  end
  self.rubuild_build_simple_dep__build_wait -= 1
  self.rubuild_build_simple_dep__parents[dep] = false
  if (self.rubuild_build_simple_dep__build_wait == 0)
    self.make_runable
  end
end

#parent_treeObject

Rubuild::Build::Dep#parent_built



336
337
338
339
340
341
342
343
344
345
346
# File 'lib/rubuild/build/simple/dep.rb', line 336

def parent_tree
  rval = Hash.new
  if self.rubuild_build_simple_dep__parents
    self.rubuild_build_simple_dep__parents.each_pair do |parent, is_waiting|
      if is_waiting
        rval["#{parent.name}"] = parent.parent_tree
      end
    end
  end
  rval
end

#runctx_build(runctx) ⇒ Object

Used by a Rubuild::Build::Context to execute the dependency command for self. Used internally.

runctx

Rubuild::Build::Context used to execute self‘s dependency command.



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/rubuild/build/simple/dep.rb', line 274

def runctx_build(runctx)
  if self.rubuild_build_simple_dep__built == true
    raise Rubuild::Build::Dep::Error::Build.new(self, runctx)
  end
  
  # propogate errors from parents.  the error may have been
  # set during the 'load' operation...
  if self.err
    raise self.err
  end
  
  # call the command, then lose the reference, so it can be
  # GC'ed.
  begin
    runctx.debug(1) do |outf|
      outf.puts("building #{self.name}")
    end
    if self.rubuild_build_simple_dep__command
      self.rubuild_build_simple_dep__command.call(
        self, *self.rubuild_build_simple_dep__args
        )
    end
  rescue Exception, NoMethodError => e
    raise self.action_error(e, runctx)
  end
  
  self.rubuild_build_simple_dep__command = nil
  self.rubuild_build_simple_dep__args = nil
  self.rubuild_build_simple_dep__built = true
  self.rubuild_build_simple_dep__loaded = nil
  self.rubuild_build_simple_dep__children.each do |child|
    child.parent_built(self)
    runctx.debug(1) do |outf|
      puts(" #{child.name} is waiting for #{child.rubuild_build_simple_dep__build_wait}:")
      runctx.debug(2) do |outf|
        if child.rubuild_build_simple_dep__parents
          child.rubuild_build_simple_dep__parents.each_pair do |child_parent, count|
            puts("  #{child_parent.name}(#{count})")
          end
        end
      end
    end
  end
  self.rubuild_build_simple_dep__children = nil
end

#set_command(command) ⇒ Object

Resets the dependency action to be invoked.

command

New command to be invoked.

return

self.



74
75
76
77
78
79
80
# File 'lib/rubuild/build/simple/dep.rb', line 74

def set_command(command)
  if self.rubuild_build_simple_dep__runable or self.rubuild_build_simple_dep__built
    raise Rubuild::Build::Dep::Error::Parameter::Command.new(self)
  end
  self.rubuild_build_simple_dep__command = command
  self
end

#surrogate(dep) ⇒ Object

Inserts dependency between self and all child dependencies of self.

dep

Dependency against which all child dependencies of self should wait.



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rubuild/build/simple/dep.rb', line 85

def surrogate(dep)
  dep.add_parent(self)
  self.rubuild_build_simple_dep__children.each do |child|
    if child != dep
      child.add_parent(dep)
    end
  end
  
  self.rubuild_build_simple_dep__loaded.each_key do |buildctx|
    dep.load(buildctx)
  end
end