Class: Rake::Task

Inherits:
Object
  • Object
show all
Defined in:
lib/rake/task.rb

Overview

A Task is the basic unit of work in a Rakefile. Tasks have associated actions (possibly more than one) and a list of prerequisites. When invoked, a task will first ensure that all of its prerequisites have an opportunity to run and then it will execute its own actions.

Tasks are not usually created directly using the new method, but rather use the file and task convenience methods.

Direct Known Subclasses

FileTask, MultiTask

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(task_name, app) ⇒ Task

Create a task named task_name with no actions or prerequisites. Use enhance to add actions and prerequisites.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rake/task.rb', line 99

def initialize(task_name, app)
  @name            = task_name.to_s
  @prerequisites   = []
  @actions         = []
  @already_invoked = false
  @comments        = []
  @lock            = Monitor.new
  @application     = app
  @scope           = app.current_scope
  @arg_names       = nil
  @locations       = []
  @invocation_exception = nil
  @order_only_prerequisites = []
end

Instance Attribute Details

#actionsObject (readonly)

List of actions attached to a task.



24
25
26
# File 'lib/rake/task.rb', line 24

def actions
  @actions
end

#already_invokedObject (readonly)

Has this task already been invoked? Already invoked tasks will be skipped unless you reenable them.



39
40
41
# File 'lib/rake/task.rb', line 39

def already_invoked
  @already_invoked
end

#applicationObject

Application owning this task.



27
28
29
# File 'lib/rake/task.rb', line 27

def application
  @application
end

#locationsObject (readonly)

File/Line locations of each of the task definitions for this task (only valid if the task was defined with the detect location option set).



35
36
37
# File 'lib/rake/task.rb', line 35

def locations
  @locations
end

#order_only_prerequisitesObject (readonly)

List of order only prerequisites for a task.



21
22
23
# File 'lib/rake/task.rb', line 21

def order_only_prerequisites
  @order_only_prerequisites
end

#prerequisitesObject (readonly) Also known as: prereqs

List of prerequisites for a task.



17
18
19
# File 'lib/rake/task.rb', line 17

def prerequisites
  @prerequisites
end

#scopeObject (readonly)

Array of nested namespaces names used for task lookup by this task.



30
31
32
# File 'lib/rake/task.rb', line 30

def scope
  @scope
end

#sourcesObject



52
53
54
55
56
57
58
# File 'lib/rake/task.rb', line 52

def sources
  if defined?(@sources)
    @sources
  else
    prerequisites
  end
end

Class Method Details

.[](task_name) ⇒ Object

Return a task with the given name. If the task is not currently known, try to synthesize one from the defined rules. If no rules are found, but an existing file matches the task name, assume it is a file task with no dependencies or actions.



404
405
406
# File 'lib/rake/task.rb', line 404

def [](task_name)
  Rake.application[task_name]
end

.clearObject

Clear the task list. This cause rake to immediately forget all the tasks that have been assigned. (Normally used in the unit tests.)



391
392
393
# File 'lib/rake/task.rb', line 391

def clear
  Rake.application.clear
end

.create_rule(*args, &block) ⇒ Object

Define a rule for synthesizing tasks.



421
422
423
# File 'lib/rake/task.rb', line 421

def create_rule(*args, &block)
  Rake.application.create_rule(*args, &block)
end

.define_task(*args, &block) ⇒ Object

Define a task given args and an option block. If a rule with the given name already exists, the prerequisites and actions are added to the existing task. Returns the defined task.



416
417
418
# File 'lib/rake/task.rb', line 416

def define_task(*args, &block)
  Rake.application.define_task(self, *args, &block)
end

.format_deps(deps) ⇒ Object

Format dependencies parameter to pass to task.



373
374
375
376
# File 'lib/rake/task.rb', line 373

def self.format_deps(deps)
  deps = [deps] unless deps.respond_to?(:to_ary)
  deps.map { |d| Rake.from_pathname(d).to_s }
end

.scope_name(scope, task_name) ⇒ Object

Apply the scope to the task name according to the rules for this kind of task. Generic tasks will accept the scope as part of the name.



428
429
430
# File 'lib/rake/task.rb', line 428

def scope_name(scope, task_name)
  scope.path_with_task_name(task_name)
end

.task_defined?(task_name) ⇒ Boolean

TRUE if the task name is already defined.

Returns:

  • (Boolean)


409
410
411
# File 'lib/rake/task.rb', line 409

def task_defined?(task_name)
  Rake.application.lookup(task_name) != nil
end

.tasksObject

List of all defined tasks.



396
397
398
# File 'lib/rake/task.rb', line 396

def tasks
  Rake.application.tasks
end

Instance Method Details

#add_description(description) ⇒ Object

Add a description to the task. The description can consist of an option argument list (enclosed brackets) and an optional comment.



298
299
300
301
302
# File 'lib/rake/task.rb', line 298

def add_description(description)
  return unless description
  comment = description.strip
  add_comment(comment) if comment && !comment.empty?
end

#all_prerequisite_tasksObject

List of all unique prerequisite tasks including prerequisite tasks’ prerequisites. Includes self when cyclic dependencies are found.



77
78
79
80
81
# File 'lib/rake/task.rb', line 77

def all_prerequisite_tasks
  seen = {}
  collect_prerequisites(seen)
  seen.values
end

#arg_descriptionObject

Argument description (nil if none).



136
137
138
# File 'lib/rake/task.rb', line 136

def arg_description # :nodoc:
  @arg_names ? "[#{arg_names.join(',')}]" : nil
end

#arg_namesObject

Name of arguments for this task.



141
142
143
# File 'lib/rake/task.rb', line 141

def arg_names
  @arg_names || []
end

#clearObject

Clear the existing prerequisites, actions, comments, and arguments of a rake task.



153
154
155
156
157
158
159
# File 'lib/rake/task.rb', line 153

def clear
  clear_prerequisites
  clear_actions
  clear_comments
  clear_args
  self
end

#clear_actionsObject

Clear the existing actions on a rake task.



168
169
170
171
# File 'lib/rake/task.rb', line 168

def clear_actions
  actions.clear
  self
end

#clear_argsObject

Clear the existing arguments on a rake task.



180
181
182
183
# File 'lib/rake/task.rb', line 180

def clear_args
  @arg_names = nil
  self
end

#clear_commentsObject

Clear the existing comments on a rake task.



174
175
176
177
# File 'lib/rake/task.rb', line 174

def clear_comments
  @comments = []
  self
end

#clear_prerequisitesObject

Clear the existing prerequisites of a rake task.



162
163
164
165
# File 'lib/rake/task.rb', line 162

def clear_prerequisites
  prerequisites.clear
  self
end

#commentObject

First line (or sentence) of all comments. Multiple comments are separated by a “/”.



322
323
324
# File 'lib/rake/task.rb', line 322

def comment
  transform_comments(" / ") { |c| first_sentence(c) }
end

#comment=(comment) ⇒ Object

:nodoc:



304
305
306
# File 'lib/rake/task.rb', line 304

def comment=(comment) # :nodoc:
  add_comment(comment)
end

#enhance(deps = nil, &block) ⇒ Object

Enhance a task with prerequisites or actions. Returns self.



115
116
117
118
119
# File 'lib/rake/task.rb', line 115

def enhance(deps=nil, &block)
  @prerequisites |= deps if deps
  @actions << block if block_given?
  self
end

#execute(args = nil) ⇒ Object

Execute the actions associated with this task.



270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/rake/task.rb', line 270

def execute(args=nil)
  args ||= EMPTY_TASK_ARGS
  if application.options.dryrun
    application.trace "** Execute (dry run) #{name}"
    return
  end
  application.trace "** Execute #{name}" if application.options.trace
  application.enhance_with_matching_rule(name) if @actions.empty?
  if opts = Hash.try_convert(args) and !opts.empty?
    @actions.each { |act| act.call(self, args, **opts) }
  else
    @actions.each { |act| act.call(self, args) }
  end
end

#full_commentObject

Full collection of comments. Multiple comments are separated by newlines.



316
317
318
# File 'lib/rake/task.rb', line 316

def full_comment
  transform_comments("\n")
end

#inspectObject

:nodoc:



46
47
48
# File 'lib/rake/task.rb', line 46

def inspect # :nodoc:
  "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>"
end

#investigationObject

Return a string describing the internal state of a task. Useful for debugging.



354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/rake/task.rb', line 354

def investigation
  result = "------------------------------\n".dup
  result << "Investigating #{name}\n"
  result << "class: #{self.class}\n"
  result <<  "task needed: #{needed?}\n"
  result <<  "timestamp: #{timestamp}\n"
  result << "pre-requisites: \n"
  prereqs = prerequisite_tasks
  prereqs.sort! { |a, b| a.timestamp <=> b.timestamp }
  prereqs.each do |p|
    result << "--#{p.name} (#{p.timestamp})\n"
  end
  latest_prereq = prerequisite_tasks.map(&:timestamp).max
  result <<  "latest-prerequisite time: #{latest_prereq}\n"
  result << "................................\n\n"
  return result
end

#invoke(*args) ⇒ Object

Invoke the task if it is needed. Prerequisites are invoked first.



186
187
188
189
# File 'lib/rake/task.rb', line 186

def invoke(*args)
  task_args = TaskArguments.new(arg_names, args)
  invoke_with_call_chain(task_args, InvocationChain::EMPTY)
end

#invoke_prerequisites(task_args, invocation_chain) ⇒ Object

Invoke all the prerequisites of a task.



237
238
239
240
241
242
243
244
245
246
# File 'lib/rake/task.rb', line 237

def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
  if application.options.always_multitask
    invoke_prerequisites_concurrently(task_args, invocation_chain)
  else
    prerequisite_tasks.each { |p|
      prereq_args = task_args.new_scope(p.arg_names)
      p.invoke_with_call_chain(prereq_args, invocation_chain)
    }
  end
end

#invoke_prerequisites_concurrently(task_args, invocation_chain) ⇒ Object

Invoke all the prerequisites of a task in parallel.



249
250
251
252
253
254
255
256
257
258
# File 'lib/rake/task.rb', line 249

def invoke_prerequisites_concurrently(task_args, invocation_chain)# :nodoc:
  futures = prerequisite_tasks.map do |p|
    prereq_args = task_args.new_scope(p.arg_names)
    application.thread_pool.future(p) do |r|
      r.invoke_with_call_chain(prereq_args, invocation_chain)
    end
  end
  # Iterate in reverse to improve performance related to thread waiting and switching
  futures.reverse_each(&:value)
end

#nameObject

Name of the task, including any namespace qualifiers.



122
123
124
# File 'lib/rake/task.rb', line 122

def name
  @name.to_s
end

#name_with_argsObject

Name of task with argument list description.



127
128
129
130
131
132
133
# File 'lib/rake/task.rb', line 127

def name_with_args # :nodoc:
  if arg_description
    "#{name}#{arg_description}"
  else
    name
  end
end

#needed?Boolean

Is this task needed?

Returns:

  • (Boolean)


286
287
288
# File 'lib/rake/task.rb', line 286

def needed?
  true
end

#prerequisite_tasksObject

List of prerequisite tasks



61
62
63
# File 'lib/rake/task.rb', line 61

def prerequisite_tasks
  (prerequisites + order_only_prerequisites).map { |pre| lookup_prerequisite(pre) }
end

#reenableObject

Reenable the task, allowing its tasks to be executed if the task is invoked again.



147
148
149
150
# File 'lib/rake/task.rb', line 147

def reenable
  @already_invoked = false
  @invocation_exception = nil
end

#set_arg_names(args) ⇒ Object

Set the names of the arguments for this task. args should be an array of symbols, one for each argument name.



348
349
350
# File 'lib/rake/task.rb', line 348

def set_arg_names(args)
  @arg_names = args.map(&:to_sym)
end

#sourceObject

First source from a rule (nil if no sources)



93
94
95
# File 'lib/rake/task.rb', line 93

def source
  sources.first
end

#timestampObject

Timestamp for this task. Basic tasks return the current time for their time stamp. Other tasks can be more sophisticated.



292
293
294
# File 'lib/rake/task.rb', line 292

def timestamp
  Time.now
end

#to_sObject

Return task name



42
43
44
# File 'lib/rake/task.rb', line 42

def to_s
  name
end

#|(deps) ⇒ Object

Add order only dependencies.



379
380
381
382
# File 'lib/rake/task.rb', line 379

def |(deps)
  @order_only_prerequisites |= Task.format_deps(deps) - @prerequisites
  self
end