class Bake::Recipe
Structured access to an instance method in a bakefile.
def <=> other
def <=> other self.source_location <=> other.source_location end
def arity
def arity if @arity.nil? @arity = method.parameters.count{|type, name| type == :req} end return @arity end
def call(*arguments, **options)
def call(*arguments, **options) if options? @instance.send(@name, *arguments, **options) else # Ignore options... @instance.send(@name, *arguments) end end
def command
def command @command ||= compute_command end
def comments
Any comments associated with the source code which defined the method.
def comments @comments ||= read_comments end
def compute_command
def compute_command path = @instance.path if path.empty? @name.to_s elsif path.last.to_sym == @name path.join(':') else (path + [@name]).join(':') end end
def documentation
The documentation object which provides structured access to the {comments}.
def documentation @documentation ||= Documentation.new(self.comments) end
def initialize(instance, name, method = nil)
@parameter name [String] The method name.
@parameter instance [Base] The instance this recipe is attached to.
Initialize the recipe.
def initialize(instance, name, method = nil) @instance = instance @name = name @command = nil @comments = nil @types = nil @documentation = nil @method = method @arity = nil end
def method
def method @method ||= @instance.method(@name) end
def options?
Whether this recipe has optional arguments.
def options? if parameters = self.parameters type, name = parameters.last return type == :keyrest || type == :keyreq || type == :key end end
def parameters
The recipe's formal parameters, if any.
def parameters parameters = method.parameters unless parameters.empty? return parameters end end
def prepare(arguments)
@returns ordered [Array]
@parameter arguments [Array(String)] The command line arguments
Process command line arguments into the ordered and optional arguments.
def prepare(arguments) offset = 0 ordered = [] options = {} parameters = method.parameters.dup types = self.types while argument = arguments.first name, value = argument.split('=', 2) if name and value # Consume it: arguments.shift if type = types[name.to_sym] value = type.parse(value) end options[name.to_sym] = value elsif ordered.size < self.arity _, name = parameters.shift value = arguments.shift if type = types[name] value = type.parse(value) end # Consume it: ordered << value else break end end return ordered, options end
def read_comments
def read_comments file, line_number = self.method.source_location lines = File.readlines(file) line_index = line_number - 1 description = [] line_index -= 1 # Extract comment preceeding method: while line = lines[line_index] # \Z matches a trailing newline: if match = line.match(COMMENT) description.unshift(match[1]) else break end line_index -= 1 end return description end
def read_types
def read_types types = {} self.documentation.parameters do |parameter| types[parameter[:name].to_sym] = Types.parse(parameter[:type]) end return types end
def source_location
def source_location self.method.source_location end
def to_s
def to_s self.command end
def types
The documented type signature of the recipe.
def types @types ||= read_types end