# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with this # work for additional information regarding copyright ownership. The ASF # licenses this file to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under # the License. module Buildr module Run include Extension class << self def runners @runners ||= [] end def select_by_lang(lang) fail 'Unable to define run task for nil language' if lang.nil? runners.detect { |e| e.languages.nil? ? false : e.languages.include?(lang.to_sym) } end alias_method :select, :select_by_lang def select_by_name(name) fail 'Unable to define run task for nil' if name.nil? runners.detect { |e| e.to_sym == name.to_sym } end end # Base class for any run provider. Defines most # common functionality (things like @lang@, @build?@ and friends). class Base attr_reader :project class << self attr_accessor :name, :languages def specify(options) @name ||= options[:name] @languages ||= options[:languages] end def to_sym @name ||= name.split('::').last.downcase.to_sym end end def initialize(project) @project = project end def build? true end def launch fail 'Not implemented' end end class RunTask < Rake::Task # Classpath dependencies. attr_accessor :classpath # Returns the run options. attr_reader :options # Returns file dependencies attr_reader :files attr_reader :project # :nodoc: def initialize(*args) # :nodoc: super @options = {} @classpath = [] @files = FileList[] end # :call-seq: # with(*artifacts) => self # # Adds files and artifacts as classpath dependencies, and returns self. def with(*specs) @classpath |= Buildr.artifacts(specs.flatten).uniq self end # :call-seq: # using(options) => self # # Sets the run options from a hash and returns self. # # For example: # run.using :main=>'org.example.Main' def using(*args) args.pop.each { |key, value| @options[key.to_sym] = value } if Hash === args.last until args.empty? new_runner = Run.select_by_name(args.pop) @runner = new_runner.new(project) unless new_runner.nil? end self end # :call-seq: # requires(*files) => self # # Adds additional files and directories as dependencies to the task and returns self. # When specifying a directory, includes all files in that directory. def requires(*files) @files.include *files.flatten.compact self end def runner @runner ||= guess_runner end # :call-seq: # runner?(clazz) => boolean # # Check if the underlying runner is an instance of the given class. # If no class is supplied, simply check if runner is defined. def runner?(clazz = nil) begin @runner ||= guess_runner if project.compile.language rescue return false end return !@runner.nil? unless clazz @runner.is_a?(clazz) if @runner end def run runner.run(self) if runner? end def prerequisites #:nodoc: super + @files + classpath end private def guess_runner runner = Run.select project.compile.language fail 'Unable to guess runner for project.' unless runner runner.new project end def associate_with(project) @project ||= project end end first_time do Project.local_task 'run' end before_define(:run => :test) do |project| RunTask.define_task('run').tap do |run| run.send(:associate_with, project) run.enhance([project.compile, project.test]) do |t| # double-enhance to execute the runner last run.enhance { |t| t.run } end end end after_define(:run => :test) do |project| project.run.with project.test.compile.dependencies project.run.with project.test.compile.target if project.test.compile.target end # :call-seq: # run(&block) => RunTask # # This method returns the project's run task. It also accepts a block to be executed # when the run task is invoked. def run(&block) task('run').tap do |t| t.enhance &block if block end end end class Project include Run end end