You are right, Buildr should not automatically extract JRuby without express permission, so I've just added a warning and prompt the user if he wants to install JRuby using the system package manager or let Buildr extract it from the artifact.
On Tue, Sep 23, 2008 at 4:43 PM, Assaf Arkin <[EMAIL PROTECTED]> wrote: > Does anyone actually use this feature? > > It strikes me as wrong that it would a) install executable code in my > home directory, b) do it without my express permission. If I need to > have JRuby installed, I'll install it using apt-get or port, both of > which install it in the right place, take care of upgrade, inventory, > etc. All Buildr has to do is notify me that it can't find JRuby. > > If people do want JRuby magically installed, maybe move this to addon > and have them include this feature in their build? > > Assaf > > On Tue, Sep 23, 2008 at 12:14 PM, <[EMAIL PROTECTED]> wrote: > > Author: vborja > > Date: Tue Sep 23 12:14:06 2008 > > New Revision: 698306 > > > > URL: http://svn.apache.org/viewvc?rev=698306&view=rev > > Log: > > Created an rspec YAMLFormatter so that buildr can know which tests > failed. > > > > Removed ci_reporter dependency > > > > Added: > > incubator/buildr/trunk/lib/buildr/java/test_result.rb > > Removed: > > incubator/buildr/trunk/lib/buildr/java/jtestr_result_handler.rb > > Modified: > > incubator/buildr/trunk/lib/buildr/java/bdd.rb > > incubator/buildr/trunk/lib/buildr/java/jtestr_runner.rb.erb > > incubator/buildr/trunk/spec/java/bdd_spec.rb > > > > Modified: incubator/buildr/trunk/lib/buildr/java/bdd.rb > > URL: > http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/java/bdd.rb?rev=698306&r1=698305&r2=698306&view=diff > > > ============================================================================== > > --- incubator/buildr/trunk/lib/buildr/java/bdd.rb (original) > > +++ incubator/buildr/trunk/lib/buildr/java/bdd.rb Tue Sep 23 12:14:06 > 2008 > > @@ -13,8 +13,8 @@ > > # License for the specific language governing permissions and > limitations under > > # the License. > > > > -require 'yaml' > > require 'buildr/java/tests' > > +require 'buildr/java/test_result' > > > > module Buildr > > > > @@ -44,6 +44,7 @@ > > end > > > > module TestFramework::JRubyBased > > + extend self > > > > VERSION = '1.1.4' unless const_defined?('VERSION') > > > > @@ -64,7 +65,11 @@ > > > > module ClassMethods > > def dependencies > > - super + (RUBY_PLATFORM[/java/] ? [] : JRubyBased.dependencies) > > + deps = super > > + unless RUBY_PLATFORM[/java/] && > TestFramework::JRubyBased.jruby_installed? > > + deps |= TestFramework::JRubyBased.dependencies > > + end > > + deps > > end > > end > > > > @@ -73,11 +78,17 @@ > > ( ENV['JRUBY_HOME'] || File.expand_path("~/.jruby") ) > > end > > > > + def jruby_installed? > > + !Dir.glob(File.join(jruby_home, 'lib', 'jruby*.jar')).empty? > > + end > > + > > def jruby(*args) > > java_args = ["org.jruby.Main", *args] > > java_args << {} unless Hash === args.last > > cmd_options = java_args.last > > project = cmd_options.delete(:project) > > + cmd_options[:classpath] ||= [] > > + Dir.glob(File.join(jruby_home, 'lib', '*.jar')) { |jar| > cmd_options[:classpath] << jar } > > cmd_options[:java_args] ||= [] > > cmd_options[:java_args] << "-Xmx512m" unless > cmd_options[:java_args].detect {|a| a =~ /^-Xmx/} > > cmd_options[:properties] ||= {} > > @@ -93,12 +104,48 @@ > > yield config if block_given? > > Java.org.jruby.Ruby.newInstance config > > end > > + > > + def jruby_gem > > + %{ > > + require 'jruby' > > + def JRuby.gem(name, version = '>0', *args) > > + require 'rbconfig' > > + jruby_home = Config::CONFIG['prefix'] > > + expected_version = '#{TestFramework::JRubyBased.version}' > > + unless JRUBY_VERSION >= expected_version > > + fail "Expected JRuby version \#{expected_version} installed > at \#{jruby_home} but got \#{JRUBY_VERSION}" > > + end > > + if Dir.glob(File.join(jruby_home, 'lib', 'jruby*.jar')).empty? > > + require 'jruby/extract' > > + JRuby::Extract.new.extract > > + end > > + require 'rubygems' > > + begin > > + Kernel.gem name, version > > + rescue LoadError, Gem::LoadError => e > > + require 'rubygems/gem_runner' > > + Gem.manage_gems > > + args = ['install', name, '--version', version] + args > > + Gem::GemRunner.new.run(args) > > + Kernel.gem name, version > > + end > > + end > > + } > > + end > > > > end > > - > > + > > + # <a href="http://rspec.info">RSpec</a> is the defacto BDD framework > for ruby. > > + # To test your project with RSpec use: > > + # test.using :rspec > > + # > > + # > > + # Support the following options: > > + # * :properties -- Hash of properties passed to the test suite. > > + # * :java_args -- Arguments passed to the JVM. > > class RSpec < TestFramework::JavaBDD > > @lang = :ruby > > - @bdd_dir = :spec > > + @bdd_dir = :spec > > > > include TestFramework::JRubyBased > > > > @@ -118,18 +165,54 @@ > > end > > > > def run(tests, dependencies) #:nodoc: > > - #jruby_home or fail "To use RSpec you must either run on JRuby or > have JRUBY_HOME set" > > + dependencies |= [task.compile.target.to_s] > > + > > cmd_options = task.options.only(:properties, :java_args) > > - #dependencies.push *Dir.glob(File.join(jruby_home, "lib/*.jar")) > if RUBY_PLATFORM =~ /java/ > > - cmd_options.update :classpath => dependencies, :project => > task.project > > + cmd_options.update :classpath => dependencies, :project => > task.project, :name => 'RSpec' > > > > report_dir = task.report_to.to_s > > FileUtils.rm_rf report_dir > > ENV['CI_REPORTS'] = report_dir > > > > - jruby '-Ilib', '-S', 'spec', '--require', > 'ci/reporter/rake/rspec_loader', > > - '--format', 'CI::Reporter::RSpecDoc', tests, > cmd_options.merge(:name => 'RSpec') > > - tests > > + result_file = File.join(report_dir, 'result.yaml') > > + > > + requires = task.options[:requires] || [] > > + requires.push 'spec', File.join(File.dirname(__FILE__), > 'test_result') > > + gems = task.options[:gems] || {} > > + argv = task.options[:args] || [ '--format', 'progress' ] > > + argv.push '--format', > "Buildr::TestFramework::TestResult::RSpec:#{result_file}" > > + argv.push *tests > > + > > + runner = %{ > > + #{ jruby_gem } > > + JRuby.gem('rspec') > > + #{ dependencies.inspect }.each { |dep| $CLASSPATH << dep } > > + #{ gems.inspect }.each { |ary| JRuby.gem(*ary.flatten) } > > + #{ requires.inspect }.each { |rb| Kernel.require rb } > > + Buildr::TestFramework::TestResult.for_rspec > > + parser = ::Spec::Runner::OptionParser.new(STDERR, STDOUT) > > + parser.order!(#{argv.inspect}) > > + $rspec_options = parser.options > > + ::Spec::Runner::CommandLine.run($rspec_options) > > + } > > + > > + runner_file = task.project.path_to(:target, :spec, > 'rspec_runner.rb') > > + Buildr.write runner_file, runner > > + > > + if /java/ === RUBY_PLATFORM > > + runtime = new_runtime :current_directory => > runner_file.pathmap('%d') > > + runtime.getLoadService.require runner_file > > + else > > + begin > > + jruby runner_file, tests, cmd_options > > + ensure > > + FileUtils.cp_r task.project.path_to(nil), '/tmp/foo' > > + end > > + end > > + > > + result = YAML.load(File.read(result_file)) > > + raise result if Exception === result > > + result.succeeded > > end > > > > end > > @@ -203,7 +286,7 @@ > > end > > > > def tests(dependencies) #:nodoc: > > - dependencies += [task.compile.target.to_s] > > + dependencies |= [task.compile.target.to_s] > > types = { :story => STORY_PATTERN, :rspec => RSpec::TESTS_PATTERN, > > :testunit => TESTUNIT_PATTERN, :expect => EXPECT_PATTERN > } > > tests = types.keys.inject({}) { |h, k| h[k] = []; h } > > @@ -220,9 +303,21 @@ > > end > > > > def run(tests, dependencies) #:nodoc: > > - dependencies += [task.compile.target.to_s] > > + dependencies |= [task.compile.target.to_s] > > + > > + result_file = File.join(task.report_to.to_s, 'result.yaml') > > + > > + requires = task.options[:requires] || [] > > + requires.push 'spec', 'jtestr', File.join(File.dirname(__FILE__), > 'test_result') > > + gems = task.options[:gems] || {} > > + argv = task.options[:args] || [ '--format', 'progress' ] > > + argv.push '--format', > "Buildr::TestFramework::TestResult::RSpec:#{result_file}" > > + argv.push *tests > > + > > + report_dir = task.report_to.to_s > > + FileUtils.rm_rf report_dir > > + ENV['CI_REPORTS'] = report_dir > > > > - yaml_report = File.join(task.report_to.to_s, 'result.yaml') > > spec_dir = task.project.path_to(:source, :spec, :ruby) > > > > runner_file = task.project.path_to(:target, :spec, > 'jtestr_runner.rb') > > @@ -237,11 +332,12 @@ > > cmd_options = task.options.only(:properties, :java_args) > > cmd_options.update(:classpath => dependencies, :project => > task.project) > > jruby runner_file, cmd_options.merge(:name => 'JtestR') > > + FileUtils.cp_r task.project.path_to(nil), '/tmp/foo' > > end > > > > - report = YAML::load(File.read(yaml_report)) > > - raise (Array(report[:error][:message]) + > report[:error][:backtrace]).join("\n") if report[:error] > > - report[:success] > > + result = YAML::load(File.read(result_file)) > > + raise result if Exception === result > > + result.succeeded > > end > > > > end > > > > Modified: incubator/buildr/trunk/lib/buildr/java/jtestr_runner.rb.erb > > URL: > http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/java/jtestr_runner.rb.erb?rev=698306&r1=698305&r2=698306&view=diff > > > ============================================================================== > > --- incubator/buildr/trunk/lib/buildr/java/jtestr_runner.rb.erb > (original) > > +++ incubator/buildr/trunk/lib/buildr/java/jtestr_runner.rb.erb Tue Sep > 23 12:14:06 2008 > > @@ -26,9 +26,14 @@ > > # <%= user_config %> > > > > begin > > - require 'jruby' > > + <%= jruby_gem %> > > + JRuby.gem('rspec') > > + > > <%= dependencies.map(&:to_s).inspect %>.each { |dep| $CLASSPATH << dep > } > > - require '<%= File.join(File.dirname(runner_erb), > "jtestr_result_handler") %>' > > + <%= gems.inspect %>.each { |ary| JRuby.gem(*ary.flatten) } > > + <%= requires.inspect %>.each { |rb| Kernel.require rb } > > + > > + Buildr::TestFramework::TestResult.for_jtestr > > > > jtestr = JtestR::TestRunner.new > > > > @@ -68,33 +73,34 @@ > > expectations <%= ts.inspect %> > > > > ignore __FILE__ > > - > > + > > if File.file?(<%= user_config.inspect %>) > > ignore <%= user_config.inspect %> > > load <%= user_config.inspect %> > > end > > end # config > > > > - args = [ '<%= spec_dir %>' ] # the directory to search for jtestr > files > > - args << JtestR::SimpleLogger::ERR # log level > > - args << JtestR::GenericResultHandler::QUIET # verbose level > > - <% if options[:output] == false %> > > - args << StringIO.new # output > > - <% elsif options[:output].kind_of?(String) %> > > - args << File.open('<%= options[:output] %>') > > - <% else %> > > - args << STDOUT # output > > - <% end %> > > - args << [] # groups_to_run > > - args << JtestR::YAMLResultHandler # result handler > > - > > - JtestR::YAMLResultHandler.report_to('<%= yaml_report %>') > > - JtestR::YAMLResultHandler.tests = <%= tests.inspect %> > > + args = [ '<%= spec_dir %>', # the directory to search for jtestr > files > > + JtestR::SimpleLogger::ERR, # log level > > + JtestR::GenericResultHandler::QUIET, #output level > > + StringIO.new, # output STDOUT > > + [], # groups to run > > + Buildr::TestFramework::TestResult::JtestR, # result handler > > + [] # classpath > > + ] > > + > > + rspec_parser = ::Spec::Runner::OptionParser.new(STDERR, STDOUT) > > + rspec_parser.order!(<%= argv.inspect %>) > > + Buildr::TestFramework::TestResult::JtestR.options = > rspec_parser.options > > + > > jtestr.run *args > > > > rescue => e > > - File.open('<%= yaml_report %>', "w") do |f| > > - f.write YAML.dump({:error => { :message => e.message, :backtrace => > e.backtrace}}) > > + puts e, *e.backtrace > > + require 'fileutils' > > + FileUtils.mkdir_p(File.dirname('<%= result_file %>')) > > + File.open('<%= result_file %>', "w") do |f| > > + f.write > YAML.dump(Buildr::TestFramework::TestResult::Error.new(e.message, > e.backtrace)) > > end > > end > > > > > > Added: incubator/buildr/trunk/lib/buildr/java/test_result.rb > > URL: > http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/java/test_result.rb?rev=698306&view=auto > > > ============================================================================== > > --- incubator/buildr/trunk/lib/buildr/java/test_result.rb (added) > > +++ incubator/buildr/trunk/lib/buildr/java/test_result.rb Tue Sep 23 > 12:14:06 2008 > > @@ -0,0 +1,207 @@ > > +# 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. > > + > > +require 'yaml' > > + > > +module Buildr #:nodoc: > > + module TestFramework > > + > > + # A class used by buildr for jruby based frameworks, so that buildr > can know > > + # which tests succeeded/failed. > > + class TestResult > > + > > + class Error < ::Exception > > + attr_reader :message, :backtrace > > + def initialize(message, backtrace) > > + @message = message > > + @backtrace = backtrace > > + end > > + end > > + > > + class << self > > + def for_rspec > > + unless const_defined?(:RSpec) > > + require 'spec/runner/formatter/base_formatter' # lazy > loading only when using Rspec > > + cls = Class.new(Spec::Runner::Formatter::BaseFormatter) { > include YamlFormatter } > > + const_set :RSpec, cls > > + end > > + end > > + > > + def for_jtestr > > + unless const_defined?(:JtestR) > > + for_rspec > > + require 'jtestr' # lazy loading only when using JtestR > > + cls = Class.new { include RSpecResultHandler } > > + const_set :JtestR, cls > > + end > > + end > > + end > > + > > + attr_accessor :failed, :succeeded > > + > > + def initialize > > + @failed, @succeeded = [], [] > > + end > > + > > + module YamlFormatter > > + attr_reader :result > > + > > + def start(example_count) > > + super > > + @result = TestResult.new > > + end > > + > > + def close > > + files = options.files > > + failure_from_bt = lambda do |ary| > > + test = nil > > + ary.find do |bt| > > + bt = bt.split(':').first.strip > > + test = bt if files.include?(bt) > > + end > > + test > > + end > > + options.reporter.instance_variable_get(:@failures).each do > |failure| > > + result.failed << > files.delete(failure_from_bt[failure.exception.backtrace]) > > + end > > + result.succeeded |= files > > + > > + FileUtils.mkdir_p(File.dirname(where)) > > + File.open(where, 'w') { |f| f.puts YAML.dump(result) } > > + end > > + end # YamlFormatter > > + > > + > > + # A JtestR ResultHandler > > + # Using this handler we can use RSpec formatters, like > html/ci_reporter with JtestR > > + # Created for YamlFormatter > > + module RSpecResultHandler > > + def self.included(mod) > > + mod.extend ClassMethods > > + super > > + end > > + > > + module ClassMethods > > + # an rspec reporter used to proxy events to rspec formatters > > + attr_reader :reporter > > + > > + def options=(options) > > + @reporter = Spec::Runner::Reporter.new(options) > > + end > > + > > + def before > > + reporter.start(reporter.options.files.size) > > + end > > + > > + def after > > + reporter.end > > + reporter.dump > > + end > > + end > > + > > + module ExampleMethods > > + attr_accessor :name, :description, :__full_description > > + end > > + > > + def reporter > > + self.class.reporter > > + end > > + > > + attr_accessor :example_group, :current_example, :current_failure > > + > > + def initialize(name, desc, *args) > > + self.example_group = ::Spec::Example::ExampleGroup.new(desc) > > + reporter.add_example_group(example_group) > > + end > > + > > + def starting > > + end > > + > > + def ending > > + end > > + > > + def add_fault(fault) > > + self.current_failure = fault > > + end > > + > > + def add_pending(pending) > > + end > > + > > + def starting_single(name = nil) > > + self.current_failure = nil > > + self.current_example = Object.new > > + current_example.extend ::Spec::Example::ExampleMethods > > + current_example.extend ExampleMethods > > + desc = name.to_s[/(.*)\(/] ? $1 : name.to_s > > + current_example.description = desc > > + current_example.__full_description = > "#{example_group.description} #{desc}" > > + reporter.example_started(current_example) > > + end > > + > > + def succeed_single(name = nil) > > + fail_unless_current(name) > > + reporter.example_finished(current_example) > > + end > > + > > + def fail_single(name = nil) > > + fail_unless_current(name) > > + reporter.failure(current_example, current_error) > > + end > > + > > + def error_single(name = nil) > > + fail_unless_current(name) > > + reporter.example_finished(current_example, current_error) > > + end > > + > > + def pending_single(name = nil) > > + fail_unless_current(name) > > + error = ::Spec::Example::ExamplePendingError.new(name) > > + reporter.example_finished(current_example, error) > > + end > > + > > + private > > + def fail_unless_current(name) > > + fail "Expected #{name.inspect} to be current example but was > #{current_example.description}" unless current_example.description == > name.to_s > > + end > > + > > + def current_error > > + fault = current_failure > > + case fault > > + when nil > > + nil > > + when Test::Unit::Failure > > + Error.new(fault.message, fault.location) > > + when Test::Unit::Error, Expectations::Results::Error, > Spec::Runner::Reporter::Failure > > + fault.exception > > + when Expectations::Results > > + fault > > + else > > + if fault.respond_to?(:test_header) > > + fault.test_header[/\((.+)\)/] > > + test = $1.to_s > > + self.class.add_failure(test) > > + elsif fault.respond_to?(:method) > > + test = fault.method.test_class.name > > + self.class.add_failure(test) > > + end > > + end > > + end > > + > > + > > + end # RSpecResultHandler > > + > > + end # TestResult > > + end > > +end > > > > Modified: incubator/buildr/trunk/spec/java/bdd_spec.rb > > URL: > http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/java/bdd_spec.rb?rev=698306&r1=698305&r2=698306&view=diff > > > ============================================================================== > > --- incubator/buildr/trunk/spec/java/bdd_spec.rb (original) > > +++ incubator/buildr/trunk/spec/java/bdd_spec.rb Tue Sep 23 12:14:06 2008 > > @@ -32,18 +32,22 @@ > > foo { test.framework.should eql(:rspec) } > > end > > > > - it 'should include src/spec/ruby/**/*_spec.rb' do > > - verbose true > > - foo do > > - spec = _('src/spec/ruby/some_spec.rb') > > - write spec, '' > > - test.invoke > > - test.tests.should include(spec) > > + it 'should run rspecs' do > > + success = File.expand_path('src/spec/ruby/success_spec.rb') > > + write(success, 'describe("success") { it("is true") { nil.should > be_nil } }') > > + failure = File.expand_path('src/spec/ruby/failure_spec.rb') > > + write(failure, 'describe("failure") { it("is false") { true.should > == false } }') > > + error = File.expand_path('src/spec/ruby/error_spec.rb') > > + write(error, 'describe("error") { it("raises") { eval("lambda") } > }') > > + foo do > > + lambda { test.invoke }.should raise_error(/Tests failed/) > > + test.tests.should include(success, failure, error) > > + test.failed_tests.should include(failure, error) > > + test.passed_tests.should include(success) > > end > > end > > > > - > > -end if RUBY_PLATFORM =~ /java/ || ENV['JRUBY_HOME'] # RSpec > > +end if true || RUBY_PLATFORM =~ /java/ || ENV['JRUBY_HOME'] # RSpec > > > > describe Buildr::JtestR do > > > > @@ -237,6 +241,8 @@ > > write(failure, 'describe("failure") { it("is false") { true.should == > false } }') > > error = File.expand_path('src/spec/ruby/error_spec.rb') > > write(error, 'describe("error") { it("raises") { eval("lambda") } }') > > + pending = File.expand_path('src/spec/ruby/pending_spec.rb') > > + write(pending, 'describe("peding") { it "is not implemented" }') > > foo do > > lambda { test.invoke }.should raise_error(/Tests failed/) > > test.tests.should include(success, failure, error) > > > > > > > -- vic Quaerendo invenietis.
