Author: boisvert
Date: Tue Oct 19 16:47:29 2010
New Revision: 1024321
URL: http://svn.apache.org/viewvc?rev=1024321&view=rev
Log:
Refactor Buildr::Shell module.
Complete standard interface: shell.with, shell.using and shell.classpath
methods.
Move Buildr::Shell::JavaRebel to Buildr::JRebel module
Add minimal specs for Buildr::Shell
(Needed before I go and add new features)
Added:
buildr/trunk/lib/buildr/core/jrebel.rb
buildr/trunk/spec/core/shell_spec.rb
Modified:
buildr/trunk/lib/buildr/core.rb
buildr/trunk/lib/buildr/core/run.rb
buildr/trunk/lib/buildr/core/shell.rb
buildr/trunk/lib/buildr/groovy/shell.rb
buildr/trunk/lib/buildr/scala/shell.rb
buildr/trunk/lib/buildr/shell.rb
buildr/trunk/spec/sandbox.rb
Modified: buildr/trunk/lib/buildr/core.rb
URL:
http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/core.rb?rev=1024321&r1=1024320&r2=1024321&view=diff
==============================================================================
--- buildr/trunk/lib/buildr/core.rb (original)
+++ buildr/trunk/lib/buildr/core.rb Tue Oct 19 16:47:29 2010
@@ -15,6 +15,7 @@
require 'buildr/core/common'
require 'buildr/core/application'
+require 'buildr/core/jrebel'
require 'buildr/core/project'
require 'buildr/core/environment'
require 'buildr/core/help'
@@ -29,3 +30,4 @@ require 'buildr/core/transports'
require 'buildr/core/generate'
require 'buildr/core/cc'
require 'buildr/core/osx' if RUBY_PLATFORM =~ /darwin/
+
Added: buildr/trunk/lib/buildr/core/jrebel.rb
URL:
http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/core/jrebel.rb?rev=1024321&view=auto
==============================================================================
--- buildr/trunk/lib/buildr/core/jrebel.rb (added)
+++ buildr/trunk/lib/buildr/core/jrebel.rb Tue Oct 19 16:47:29 2010
@@ -0,0 +1,39 @@
+# 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 JRebel
+ def jrebel_home
+ unless @jrebel_home
+ @jrebel_home = ENV['REBEL_HOME'] || ENV['JREBEL'] || ENV['JREBEL_HOME']
+ end
+
+ (@rebel_home && File.exists?(@rebel_home)) ? @jrebel_home : nil
+ end
+
+ def rebel_jar
+ @rebel_home ? File.join(@jrebel_home, 'jrebel.jar') : nil
+ end
+
+ def jrebel_argss
+ rebel_jar ? [ '-noverify', "-javaagent:#{rebel_jar}" ] : []
+ end
+
+ def jrebel_props(project)
+ {}
+ end
+ end
+end
+
Modified: buildr/trunk/lib/buildr/core/run.rb
URL:
http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/core/run.rb?rev=1024321&r1=1024320&r2=1024321&view=diff
==============================================================================
--- buildr/trunk/lib/buildr/core/run.rb (original)
+++ buildr/trunk/lib/buildr/core/run.rb Tue Oct 19 16:47:29 2010
@@ -21,7 +21,7 @@ module Buildr
module Run
class JavaRunner < Base
- include Shell::JavaRebel
+ include Buildr::JRebel
specify :name => :java, :languages => [:java, :scala, :groovy, :clojure]
@@ -29,9 +29,9 @@ module Buildr
fail "Missing :main option" unless task.options[:main]
cp = project.compile.dependencies + [project.path_to(:target,
:classes)] + task.classpath
Java::Commands.java(task.options[:main], {
- :properties => rebel_props(project).merge(task.options[:properties]
|| {}),
+ :properties => jrebel_props(project).merge(task.options[:properties]
|| {}),
:classpath => cp,
- :java_args => rebel_args + (task.options[:java_args] || [])
+ :java_args => jrebel_argss + (task.options[:java_args] || [])
})
end
end # JavaRunnner
Modified: buildr/trunk/lib/buildr/core/shell.rb
URL:
http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/core/shell.rb?rev=1024321&r1=1024320&r2=1024321&view=diff
==============================================================================
--- buildr/trunk/lib/buildr/core/shell.rb (original)
+++ buildr/trunk/lib/buildr/core/shell.rb Tue Oct 19 16:47:29 2010
@@ -22,11 +22,12 @@ module Buildr
module Shell
class BeanShell < Base
-
- include JavaRebel
+ include Buildr::JRebel
VERSION = '2.0b4'
+ specify :name => :bsh, :languages => [:java]
+
class << self
def version
Buildr.settings.build['bsh'] || VERSION
@@ -35,22 +36,14 @@ module Buildr
def artifact
"org.beanshell:bsh:jar:#{version}"
end
-
- def lang
- :java
- end
-
- def to_sym
- :bsh
- end
end
- def launch
+ def launch(task)
cp = project.compile.dependencies + [project.path_to(:target,
:classes), Buildr.artifact(BeanShell.artifact)]
Java::Commands.java 'bsh.Console', {
- :properties => rebel_props(project),
+ :properties => jrebel_props(project),
:classpath => cp,
- :java_args => rebel_args
+ :java_args => jrebel_argss
}
end
@@ -58,17 +51,11 @@ module Buildr
class JIRB < Base
- include JavaRebel
+ include JRebel
JRUBY_VERSION = '1.4.0'
- class << self
- def lang
- :none
- end
- end
-
- def launch
+ def launch(task)
if jruby_home # if JRuby is installed, use it
cp = project.compile.dependencies +
[project.path_to(:target, :classes)] +
@@ -107,9 +94,9 @@ module Buildr
]
Java::Commands.java 'org.jruby.Main',
"#{jruby_home}#{File::SEPARATOR}bin#{File::SEPARATOR}jirb", {
- :properties => props.merge(rebel_props(project)),
+ :properties => props.merge(jrebel_props(project)),
:classpath => cp,
- :java_args => args + rebel_args
+ :java_args => args + jrebel_argss
}
else
cp = project.compile.dependencies + [
@@ -118,12 +105,13 @@ module Buildr
]
Java::Commands.java 'org.jruby.Main', '--command', 'irb', {
- :properties => rebel_props(project),
+ :properties => jrebel_props(project),
:classpath => cp,
- :java_args => rebel_args
+ :java_args => jrebel_argss
}
end
end
+
private
def jruby_home
@jruby_home ||= RUBY_PLATFORM =~ /java/ ? Config::CONFIG['prefix'] :
ENV['JRUBY_HOME']
@@ -137,7 +125,7 @@ module Buildr
end
class Clojure < Base
- include JavaRebel
+ include JRebel
JLINE_VERSION = '0.9.94'
@@ -156,7 +144,7 @@ module Buildr
!has_source?(:clojure) or has_source?(:java) or has_source?(:scala) or
has_source?(:groovy)
end
- def launch
+ def launch(task)
fail 'Are we forgetting something? CLOJURE_HOME not set.' unless
clojure_home
cp = project.compile.dependencies +
@@ -172,9 +160,9 @@ module Buildr
if build?
Java::Commands.java 'jline.ConsoleRunner', 'clojure.lang.Repl', {
- :properties => rebel_props(project),
+ :properties => jrebel_props(project),
:classpath => cp,
- :java_args => rebel_args
+ :java_args => jrebel_argss
}
else
Java::Commands.java 'jline.ConsoleRunner', 'clojure.lang.Repl',
:classpath => cp
@@ -193,6 +181,6 @@ module Buildr
end
end
-Buildr::ShellProviders << Buildr::Shell::BeanShell
-Buildr::ShellProviders << Buildr::Shell::JIRB
-Buildr::ShellProviders << Buildr::Shell::Clojure
+Buildr::Shell.providers << Buildr::Shell::BeanShell
+Buildr::Shell.providers << Buildr::Shell::JIRB
+Buildr::Shell.providers << Buildr::Shell::Clojure
Modified: buildr/trunk/lib/buildr/groovy/shell.rb
URL:
http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/groovy/shell.rb?rev=1024321&r1=1024320&r2=1024321&view=diff
==============================================================================
--- buildr/trunk/lib/buildr/groovy/shell.rb (original)
+++ buildr/trunk/lib/buildr/groovy/shell.rb Tue Oct 19 16:47:29 2010
@@ -20,13 +20,9 @@ module Buildr
class GroovySH < Buildr::Shell::Base
SUFFIX = if Util.win_os? then '.bat' else '' end
- class << self
- def lang
- :groovy
- end
- end
+ specify :name => :groovy, :languages => [:groovy]
- def launch
+ def launch(task)
fail 'Are we forgetting something? GROOVY_HOME not set.' unless
groovy_home
cp = project.compile.dependencies.join(File::PATH_SEPARATOR) +
@@ -45,4 +41,4 @@ module Buildr
end
end
-Buildr::ShellProviders << Buildr::Groovy::GroovySH
+Buildr::Shell.providers << Buildr::Groovy::GroovySH
Modified: buildr/trunk/lib/buildr/scala/shell.rb
URL:
http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/scala/shell.rb?rev=1024321&r1=1024320&r2=1024321&view=diff
==============================================================================
--- buildr/trunk/lib/buildr/scala/shell.rb (original)
+++ buildr/trunk/lib/buildr/scala/shell.rb Tue Oct 19 16:47:29 2010
@@ -20,41 +20,31 @@ require 'buildr/java/commands'
module Buildr
module Scala
class ScalaShell < Buildr::Shell::Base
- include Buildr::Shell::JavaRebel
+ include Buildr::JRebel
- class << self
- def lang
- :scala
- end
-
- def to_sym
- :scala
- end
- end
+ specify :name => :scala, :languages => [:scala]
- def launch
- cp = project.compile.dependencies +
- Scalac.dependencies +
- [project.path_to(:target, :classes)]
+ def launch(task)
+ cp = project.compile.dependencies + Scalac.dependencies +
[project.path_to(:target, :classes)]
- props = {
- 'scala.home' => Scalac.scala_home
- }
+ java_args = task.options[:java_args] || (ENV['JAVA_OPTS'] ||
ENV['JAVA_OPTIONS']).to_s.split
+
+ props = jrebel_props(project)
+ props = props.merge(task.options[:properties]) if
task.options[:properties]
+ props = props.merge 'scala.home' => Scalac.scala_home
- jline = [File.expand_path("lib/jline.jar",
Scalac.scala_home)].find_all do |f|
- File.exist? f
- end
+ jline = [File.expand_path("lib/jline.jar",
Scalac.scala_home)].find_all { |f| File.exist? f }
Java::Commands.java 'scala.tools.nsc.MainGenericRunner',
'-cp', cp.join(File::PATH_SEPARATOR),
{
- :properties => props.merge(rebel_props(project)),
+ :properties => props,
:classpath => Scalac.dependencies + jline,
- :java_args => rebel_args
+ :java_args => jrebel_argss
}
end
end
end
end
-Buildr::ShellProviders << Buildr::Scala::ScalaShell
+Buildr::Shell.providers << Buildr::Scala::ScalaShell
Modified: buildr/trunk/lib/buildr/shell.rb
URL:
http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/shell.rb?rev=1024321&r1=1024320&r2=1024321&view=diff
==============================================================================
--- buildr/trunk/lib/buildr/shell.rb (original)
+++ buildr/trunk/lib/buildr/shell.rb Tue Oct 19 16:47:29 2010
@@ -15,166 +15,163 @@
module Buildr
- module ShellProviders
+ module Shell
+ include Extension
+
class << self
- def add(p)
- @providers ||= {}
+ def providers
+ @providers ||= []
+ end
- if p.lang == :none
- @providers[:none] ||= []
- @providers[:none] << p
- else
- @providers[p.lang] = p
- end
+ def select_by_lang(lang)
+ fail 'Unable to define shell task for nil language' if lang.nil?
+ providers.detect { |e| e.languages.nil? ? false :
e.languages.include?(lang.to_sym) }
end
- alias :<< :add
- def providers
- @providers ||= {}
+ alias_method :select, :select_by_lang
+
+ def select_by_name(name)
+ fail 'Unable to define run task for nil' if name.nil?
+ providers.detect { |e| e.to_sym == name.to_sym }
end
- def each
- providers.each do |lang, p|
- if lang == :none
- p.each do |x|
- yield x
- end
- else
- yield p
+ def define_task(project, name, provider = nil)
+ ShellTask.define_task(name).tap do |t|
+ t.send(:associate_with, project)
+ t.enhance([project.compile]) do |t|
+ # double-enhance to execute the provider last
+ t.enhance { |t| t.run }
end
+ t.using provider.to_sym if provider
end
end
end
- end
-
- module Shell
- class Base
- attr_reader :project
- class << self
- def lang
- :none
- end
-
- def to_sym
- @symbol ||= name.split('::').last.downcase.to_sym
- end
- end
+ first_time do
+ Project.local_task 'shell'
- def initialize(project)
- @project = project
- end
+ providers.each { |provider| Project.local_task
"shell:#{provider.to_sym}" }
+ end
- def build?
- true
- end
+ before_define(:shell => :compile) do |project|
+ define_task(project, "shell")
+ providers.each { |provider| define_task(project,
"shell:#{provider.to_sym}", provider) }
+ end
- def launch
- fail 'Not implemented'
+ after_define(:shell => :compile) do |project|
+ unless project.shell.provider
+ provider = providers.find { |p| p.languages.include?
project.compile.language if p.languages }
+ if provider
+ project.shell.using provider.to_sym
+ project.shell.with project.test.compile.dependencies
+ end
end
end
- module JavaRebel
- def rebel_home
- unless @rebel_home
- @rebel_home = ENV['REBEL_HOME'] || ENV['JREBEL'] ||
ENV['JREBEL_HOME']
+ # Base class for any shell provider.
+ class Base
+ attr_reader :project # :nodoc:
- if @rebel_home and File.directory? @rebel_home
- @rebel_home += File::SEPARATOR + 'jrebel.jar'
- end
- end
+ class << self
+ attr_accessor :shell_name, :languages
- if @rebel_home and File.exists? @rebel_home
- @rebel_home
- else
- nil
+ def specify(options)
+ @shell_name ||= options[:name]
+ @languages ||= options[:languages]
end
- end
- def rebel_args
- if rebel_home
- [
- '-noverify',
- "-javaagent:#{rebel_home}"
- ]
- else
- []
+ def to_sym
+ @shell_name || name.split('::').last.downcase.to_sym
end
end
- def rebel_props(project)
- {}
+ def initialize(project)
+ @project = project
end
- end
- end
-
- module ShellExtension
- include Extension
- first_time do
- Project.local_task 'shell'
+ def launch(task)
+ fail 'Not implemented'
+ end
- ShellProviders.each { |p| Project.local_task "shell:#{p.to_sym}" } #
TODO not working
end
- before_define(:shell => :compile) do |project|
- ShellProviders.each do |p|
- name = p.to_sym
+ class ShellTask < Rake::Task
+ attr_reader :project # :nodoc:
- trace "Defining task #{project.name}:shell:#{name}"
+ # Classpath dependencies.
+ attr_accessor :classpath
- p_inst = p.new project
- deps = if p_inst.build? then [:compile] else [] end
+ # Returns the run options.
+ attr_reader :options
- project.task "shell:#{name}" => deps do
- trace "Launching #{name} shell"
- p_inst.launch
+ # Underlying shell provider
+ attr_reader :provider
+
+ def initialize(*args) # :nodoc:
+ super
+ @options = {}
+ @classpath = []
+ 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:
+ # shell.using :properties => {'foo' => 'bar'}
+ # shell.using :bsh
+ def using(*args)
+ if Hash === args.last
+ args.pop.each { |key, value| @options[key.to_sym] = value }
end
- end
- end
- after_define(:shell => :compile) do |project|
- default_shell = project.shell.using
-
- if default_shell
- dep = "shell:#{default_shell.to_sym}"
-
- trace "Defining task shell based on #{dep}"
- project.task :shell => dep
- else
- project.task :shell do
- fail "No shell provider defined for language
'#{project.compile.language}'"
+ until args.empty?
+ new_shell = Shell.select_by_name(args.pop)
+ @provider = new_shell.new(project) unless new_shell.nil?
end
+
+ self
end
- end
- class ShellConfig
- def initialize(project)
- @project = project
+ def run
+ fail "No shell provider defined in project '#{project.name}' for
language '#{project.compile.language.inspect}'" unless provider
+ provider.launch(self)
end
- def using(*args)
- if args.size > 0
- @using ||= args.first
- else
- @using ||= find_shell_task
- end
+ def prerequisites #:nodoc:
+ super + classpath
end
private
- def find_shell_task
- lang = @project.compile.language
- ShellProviders.providers[lang]
+ def associate_with(project)
+ @project ||= project
end
+
end
- # TODO temporary hack
- def shell
- @shell ||= ShellConfig.new self
+ # :call-seq:
+ # shell(&block) => ShellTask
+ #
+ # This method returns the project's shell task. It also accepts a block to
be executed
+ # when the shell task is invoked.
+ def shell(&block)
+ task('shell').tap do |t|
+ t.enhance &block if block
+ end
end
end
class Project
- include ShellExtension
+ include Shell
end
end
Added: buildr/trunk/spec/core/shell_spec.rb
URL:
http://svn.apache.org/viewvc/buildr/trunk/spec/core/shell_spec.rb?rev=1024321&view=auto
==============================================================================
--- buildr/trunk/spec/core/shell_spec.rb (added)
+++ buildr/trunk/spec/core/shell_spec.rb Tue Oct 19 16:47:29 2010
@@ -0,0 +1,124 @@
+# 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 File.expand_path(File.join(File.dirname(__FILE__), '..',
'spec_helpers'))
+
+describe Project, '.shell' do
+
+ it 'should return the project\'s shell task' do
+ define('foo')
+ project('foo').shell.name.should eql('foo:shell')
+ end
+
+ it 'should return a ShellTask' do
+ define('foo')
+ project('foo').shell.should be_kind_of(Shell::ShellTask)
+ end
+
+ it 'should include compile and test.compile dependencies' do
+ define('foo') do
+ compile.using(:javac).with 'group:compile:jar:1.0'
+ test.compile.using(:javac).with 'group:test:jar:1.0'
+ end
+ project('foo').shell.classpath.should
include(artifact('group:compile:jar:1.0'))
+ project('foo').shell.classpath.should
include(artifact('group:test:jar:1.0'))
+ end
+
+ it 'should respond to using() and return self' do
+ define 'foo' do
+ shell.using(:foo=>'Fooing').should be(shell)
+ end
+ end
+
+ it 'should respond to using() and accept options' do
+ define 'foo' do
+ shell.using :foo=>'Fooing'
+ end
+ project('foo').shell.options[:foo].should eql('Fooing')
+ end
+
+ it 'should select provider using shell.using' do
+ define 'foo' do
+ shell.using :bsh
+ end
+ project('foo').shell.provider.should be_a(Shell::BeanShell)
+ end
+
+ it 'should select runner based on compile language' do
+ write 'src/main/java/Test.java', 'class Test {}'
+ define 'foo' do
+ # compile language detected as :java
+ end
+ project('foo').shell.provider.should be_a(Shell::BeanShell)
+ end
+
+ it 'should depend on project''s compile task' do
+ define 'foo'
+ project('foo').shell.prerequisites.should include(project('foo').compile)
+ end
+
+ it 'should be local task' do
+ define 'foo' do
+ define('bar') do
+ shell.using :bsh
+ end
+ end
+ task = project('foo:bar').shell
+ task.should_receive(:invoke_prerequisites)
+ task.should_receive(:run)
+ in_original_dir(project('foo:bar').base_dir) { task('shell').invoke }
+ end
+
+ it 'should not recurse' do
+ define 'foo' do
+ shell.using :bsh
+ define('bar') { shell.using :bsh }
+ end
+ project('foo:bar').shell.should_not_receive(:invoke_prerequisites)
+ project('foo:bar').shell.should_not_receive(:run)
+ project('foo').shell.should_receive(:run)
+ project('foo').shell.invoke
+ end
+
+ it 'should call shell provider with task configuration' do
+ define 'foo' do
+ shell.using :bsh
+ end
+ shell = project('foo').shell
+ shell.provider.should_receive(:launch).with(shell)
+ project('foo').shell.invoke
+ end
+end
+
+describe "shell provider", :shared=>true do
+
+ it 'should have launch method accepting shell task' do
+ @instance.method(:launch).should_not be_nil
+ @instance.method(:launch).arity.should === 1
+ end
+end
+
+Shell.providers.each do |provider|
+ describe provider do
+ before do
+ @provider = provider
+ @project = define('foo') {}
+ @instance = provider.new(@project)
+ end
+
+ it_should_behave_like "shell provider"
+ end
+end
+
Modified: buildr/trunk/spec/sandbox.rb
URL:
http://svn.apache.org/viewvc/buildr/trunk/spec/sandbox.rb?rev=1024321&r1=1024320&r2=1024321&view=diff
==============================================================================
--- buildr/trunk/spec/sandbox.rb (original)
+++ buildr/trunk/spec/sandbox.rb Tue Oct 19 16:47:29 2010
@@ -33,7 +33,8 @@ artifacts(
TestFramework.frameworks.map(&:dependencies).flatten,
JUnit.ant_taskdef,
Buildr::Groovy::Groovyc.dependencies,
- Buildr::Scala::Specs.dependencies
+ Buildr::Scala::Specs.dependencies,
+ Buildr::Shell::BeanShell.artifact
).each do |path|
file(path).invoke
end