| Class | Sprout::ToolTask |
| In: |
sprout/lib/sprout/tasks/tool_task.rb
|
| Parent: | Rake::FileTask |
The ToolTask provides some base functionality for any Command Line Interface (CLI) tool. It also provides support for GUI tools that you would like to expose from the Command Line (Like the Flash Player for example).
ToolTask extends Rake::FileTask, and should be thought of in the same way. Martin Fowler did a much better job of describing Rake and specifically FileTasks than I can in his (now classic) Rake article from 2005.
What this means is that most tool task instances should be named for the file that they will create. For example, an Sprout::MXMLCTask instance should be named for the SWF that it will generate.
mxmlc 'bin/SomeProject.swf' => :corelib do |t|
t.input = 'src/SomeProject.as'
t.default_size = '800 600'
end
In general, a tool task will only be executed if it‘s output file (name) does not exist or if the output file is older than any file identified as a prerequisite.
Many of the compiler tasks take advantage of this feature by opting out of unnecessary compilation.
Subclasses can add and configure command line parameters by calling the protected add_param method that is implemented on this class.
# File sprout/lib/sprout/tasks/tool_task.rb, line 34 def self.add_preprocessed_task(name) @@preprocessed_tasks[name] = true end
# File sprout/lib/sprout/tasks/tool_task.rb, line 42 def self.clear_preprocessed_tasks @@preprocessed_tasks.clear end
# File sprout/lib/sprout/tasks/tool_task.rb, line 56 def self.define_task(args, &block) t = super if(t.is_a?(ToolTask)) yield t if block_given? t.define t.prepare end return t end
# File sprout/lib/sprout/tasks/tool_task.rb, line 38 def self.has_preprocessed_task?(name) !@@preprocessed_tasks[name].nil? end
Returns arguments that were appended at the end of the command line output
# File sprout/lib/sprout/tasks/tool_task.rb, line 144 def appended_args @appended_args end
Arguments to appended at the end of the command line output
# File sprout/lib/sprout/tasks/tool_task.rb, line 139 def appended_args=(args) @appended_args = args end
The default file expression to append to each PathParam in order to build file change prerequisites.
Defaults to ’/**/**/*’
# File sprout/lib/sprout/tasks/tool_task.rb, line 244 def default_file_expression @default_file_expression ||= '/**/**/*' end
# File sprout/lib/sprout/tasks/tool_task.rb, line 235 def define resolve_libraries(prerequisites) end
# File sprout/lib/sprout/tasks/tool_task.rb, line 199 def execute(*args) display_preprocess_message #puts ">> Executing #{File.basename(exe)} #{to_shell}" exe = Sprout.get_executable(gem_name, gem_path, gem_version) User.execute(exe, to_shell) end
Full name of the sprout tool gem that this tool task will use. For example, the MXMLCTask uses the sprout-flex3sdk-tool at the time of this writing, but will at some point change to use the sprout-flex3sdk-tool. You can combine this value with gem_version in order to specify exactly which gem your tool task is executing.
# File sprout/lib/sprout/tasks/tool_task.rb, line 70 def gem_name return @gem_name ||= @default_gem_name end
The exact gem version that you would like the ToolTask to execute. By default this value should be nil and will download the latest version of the gem that is available unless there is a version already installed on your system.
This attribute could be an easy way to update your local gem to the latest version without leaving your build file, but it‘s primary purpose is to allow you to specify very specific versions of the tools that your project depends on. This way your team can rest assured that they are all working with the same tools.
# File sprout/lib/sprout/tasks/tool_task.rb, line 87 def gem_version return @gem_version ||= nil end
# File sprout/lib/sprout/tasks/tool_task.rb, line 91 def gem_version=(version) @gem_version = version end
An Array of all parameters that have been added to this Tool.
# File sprout/lib/sprout/tasks/tool_task.rb, line 220 def params @params ||= [] end
Called after initialize and define, usually subclasses should only override define.
# File sprout/lib/sprout/tasks/tool_task.rb, line 226 def prepare # Get each added param to inject prerequisites as necessary params.each do |param| param.prepare end # Ensure there are no duplicates in the prerequisite collection @prerequisites = prerequisites.uniq end
Returns arguments that were prepended in front of the command line output
# File sprout/lib/sprout/tasks/tool_task.rb, line 134 def prepended_args @prepended_args end
Arguments to be prepended in front of the command line output
# File sprout/lib/sprout/tasks/tool_task.rb, line 129 def prepended_args=(args) @prepended_args = args end
# File sprout/lib/sprout/tasks/tool_task.rb, line 189 def preprocessed_path @preprocessed_path ||= '.preprocessed' end
Path where preprocessed files are stored. Defaults to ’.preprocessed‘
# File sprout/lib/sprout/tasks/tool_task.rb, line 185 def preprocessed_path=(preprocessed_path) @preprocessed_path = preprocessed_path end
Command line arguments to execute preprocessor. The preprocessor execution should accept text via STDIN and return its processed content via STDOUT.
In the following example, the MXMLCTask has been configured to use the C preprocessor (cpp) and place the processed output into a _preprocessed folder, instead of the hidden default folder at .preprocessed.
One side effect of the cpp tool is that it adds 2 carriage returns to the top of any processed files, so we have simply piped its output to the tail command which then strips those carriage returns from all files - which retains accurate line numbers for any compiler error messages.
mxmlc 'bin/SomeProject.swf' => :corelib do |t|
t.input = 'src/SomeProject.as'
t.default_size = '800 600'
t.preprocessor = 'cpp -D__DEBUG=true -P - - | tail -c +3'
t.preprocessed_path = '_preprocessed'
end
Any source files found in this example project can now take advantage of any tools, macros or syntax available to CPP. For example, the __DEBUG variable is now defined and can be accessed in ActionScript source code as follows:
public static const DEBUG:Boolean = __DEBUG;
Any commandline tool identified on this attribute will be provided the content of each file on STDIN and whatever it returns to STDOUT will be written into the preprocessed_path. This means that we can take advantage of the entire posix tool chain by piping inputs and outputs from one tool to another. Whatever the last tool returns will be handed off to the concrete compiler.
# File sprout/lib/sprout/tasks/tool_task.rb, line 176 def preprocessor=(preprocessor) @preprocessor = preprocessor end
Create a string that can be turned into a file that rdoc can parse to describe the customized or generated task using param name, type and description
# File sprout/lib/sprout/tasks/tool_task.rb, line 105 def to_rdoc result = '' parts = self.class.to_s.split('::') class_name = parts.pop module_count = 0 while(module_name = parts.shift) result << "module #{module_name}\n" module_count += 1 end result << "class #{class_name} < ToolTask\n" params.each do |param| result << param.to_rdoc end while((module_count -= 1) >= 0) result << "end\nend\n" end return result end
Create a string that represents this configured tool for shell execution
# File sprout/lib/sprout/tasks/tool_task.rb, line 207 def to_shell result = [] result << @prepended_args unless @prepended_args.nil? params.each do |param| if(param.visible?) result << param.to_shell end end result << @appended_args unless @appended_args.nil? return result.join(' ') end
add_param is the workhorse of the ToolTask. This method is used to add new shell parameters to the task. name is a symbol or string that represents the parameter that you would like to add such as :debug or :source_path. type is usually sent as a Ruby symbol and can be one of the following:
Be sure to check out the Sprout::TaskParam class to learn more about block editing the parameters.
Once parameters have been added using the add_param method, clients can set and get those parameters from the newly created task.
# File sprout/lib/sprout/tasks/tool_task.rb, line 282 def add_param(name, type, &block) # :yields: Sprout::TaskParam name = name.to_s # First ensure the named accessor doesn't yet exist... if(param_hash[name]) raise ToolTaskError.new("TaskBase.add_param called with existing parameter name: #{name}") end param = create_param(type) param.init do |p| p.belongs_to = self p.name = name p.type = type yield p if block_given? end param_hash[name] = param params << param end
Alias an existing parameter with another name. For example, the existing parameter :source_path might be given an alias ’-sp’ as follows:
add_param_alias(:sp, :source_path)
Alias parameters cannot be configured differently from the parameter that they alias
# File sprout/lib/sprout/tasks/tool_task.rb, line 310 def add_param_alias(name, other_param) if(param_hash.has_key? other_param.to_s) param_hash[name.to_s] = param_hash[other_param.to_s] else raise ToolTaskError.new("TaskBase.add_param_alis called with") end end
If the provided path contains spaces, wrap it in quotes so that shell tools won‘t choke on the spaces
# File sprout/lib/sprout/tasks/tool_task.rb, line 378 def clean_path(path) if(path.index(' ')) path = %{"#{path}"} end return path end
# File sprout/lib/sprout/tasks/tool_task.rb, line 320 def create_param(type) return eval("#{type.to_s.capitalize}Param.new") end
# File sprout/lib/sprout/tasks/tool_task.rb, line 340 def method_missing(name,*args) name = name.to_s cleaned = clean_name(name) if(!respond_to?(cleaned)) raise NoMethodError.new("undefined method '#{name}' for #{self.class}", name) end param = param_hash[cleaned] if(name =~ /=$/) param.value = args.shift elsif(param) param.value else raise ToolTaskError.new("method_missing called with undefined parameter [#{name}]") end end
Iterate over all prerequisites looking for any that are a LibraryTask. Concrete ToolTask implementations should override resolve_library in order to add the library sources or binaries appropriately.
# File sprout/lib/sprout/tasks/tool_task.rb, line 362 def resolve_libraries(prerequisites) prerequisites.each do |prereq| instance = Rake::application[prereq] if(instance.is_a?(LibraryTask)) resolve_library(instance) end end end
Concrete ToolTasks should override this method and add any dependent libraries appropriately
# File sprout/lib/sprout/tasks/tool_task.rb, line 373 def resolve_library(library_task) end
# File sprout/lib/sprout/tasks/tool_task.rb, line 328 def respond_to?(name) result = super if(!result) result = param_hash.has_key? name end return result end