Author: assaf
Date: Fri Mar 21 16:59:34 2008
New Revision: 639925
URL: http://svn.apache.org/viewvc?rev=639925&view=rev
Log:
More test cases for addons
Modified:
incubator/buildr/trunk/doc/pages/more_stuff.textile
incubator/buildr/trunk/lib/core/addon.rb
incubator/buildr/trunk/spec/addon_spec.rb
Modified: incubator/buildr/trunk/doc/pages/more_stuff.textile
URL:
http://svn.apache.org/viewvc/incubator/buildr/trunk/doc/pages/more_stuff.textile?rev=639925&r1=639924&r2=639925&view=diff
==============================================================================
--- incubator/buildr/trunk/doc/pages/more_stuff.textile (original)
+++ incubator/buildr/trunk/doc/pages/more_stuff.textile Fri Mar 21 16:59:34 2008
@@ -1,6 +1,82 @@
h1. More Stuff
+h2. Addons
+
+Addons allow you to package and distribute common extensions, tasks and
+features for use with different buildfiles.
+
+Addons are based on "RubyGems":http://www.rubygems.org/, a packaging and
+distribution mechanism for Ruby libraries. Buildr itself is packaged as a Ruby
+gem, as are most of its dependencies. Managing gems is done through the @gem@
+command line tool.
+
+The @require@ method allows you to include any Ruby file contained in a
+previously installed gem. If multiple versions are installed, it will default
to
+the most recent version. You can change it to use a particular version with
the
[EMAIL PROTECTED]@ method, for example:
+
+{{{!ruby
+gem 'highline', '~> 1.4'
+require 'highline'
+}}}
+
+The @addon@ method replaces the @gem@ method and adds a couple of conveniences
+specifically for use in buildfiles. Like the @gem@ method, it will activate
+the most recent version allowed. However, if the gem does not already exists
+in the local repository, it will attempt to download and install it from one of
+the remote gem repositories.
+
+In addition, it will activate the gem.
+
+
+The @addon@ method provides a convenient way to download and install a
+particular gem and make it available in your buildfile. The method takes two
+arguments, the gem name and an optional version requirement. For example:
+
+{{{!
+# Latest version of extra and version 2.2 of shared.
+addon 'extra'
+addon 'shared', '2.2'
+}}}
+
+The version requirement can be an exact version number, or combine a comparison
+operator with a version number.
+
+Supported comparison operators are @=@, @!=@, @>@, @<@, @>=@, @<=@ and @~>@.
+The compatible comparison (@~>@) matches from the specified version up one
version.
+For example, @~> 5.3.1@ will match all versions from 5.3.1 up to but excluding
5.4,
+while @~> 5.3@ will match all versions from 5.3.0 up to but excluding 6.
+
+If multiple versions match, the highest is always picked. The default version
+requirement, if unspecified, is @'>= [EMAIL PROTECTED] You can always use an
array for more
+precise control, for example, to support all versions from 1.0 through 1.7,
+exclusing 1.3: @['>= 1.0', '<= 1.7', '!= 1.3'[EMAIL PROTECTED]
+
+When running the build, the @addon@ methods attempts to find and activate the
+named gem from the local Gem repository. If it can't find the gem or a
matching
+version, it will attempt to download it from one of the remote gem
repositories.
+
+What happens next depends on the specific addon. The @addon@ method will load
+Ruby files places in the gem's require paths. Some addons will use that to
+define methods, extend @Project@, define tasks, etc. It will also import all
[EMAIL PROTECTED]@ files found in the gem's @tasks@ directory, which can be
used to
+provide additional tasks. Last, some addons will do nothing, but will make
+features available for inclusion, typically using a subsequent @[EMAIL
PROTECTED]
+Consult the addon's documentation for more details.
+
+RubyGems uses the "RubyForge gems repository":http://gems.rubyforge.org/ as the
+default remote repository. You can add additional sources using the @gem
+sources@ command, for example:
+
+{{{!sh
+$ # View all sources
+$ gem sources --list
+$ # Add another repository
+$ gem sources --add http://gems.example.com
+}}}
+
+
h2. Using Java Libraries
Buildr runs along side a JVM, using either RJB or JRuby. The Java module
Modified: incubator/buildr/trunk/lib/core/addon.rb
URL:
http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/addon.rb?rev=639925&r1=639924&r2=639925&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/addon.rb (original)
+++ incubator/buildr/trunk/lib/core/addon.rb Fri Mar 21 16:59:34 2008
@@ -49,8 +49,12 @@
spec = Gem::Format.from_file_by_path(path).spec
when String
dep = Gem::Dependency.new(name_or_path, version)
- spec = Gem::SourceIndex.from_installed_gems.search(dep).last ||
Gem::SourceInfoCache.search(dep).last
- fail Gem::LoadError, "Could not find #{name_or_path} locally or in
remote repository." unless spec
+ #spec = Gem::SourceIndex.from_installed_gems.search(dep).last ||
Gem::SourceInfoCache.search(dep).last
+ unless spec = Gem::SourceIndex.from_installed_gems.search(dep).last
+ Gem::SourceInfoCache.search(dep).last
+ Gem::SourceInfoCache.cache.flush
+ fail Gem::LoadError, "Could not find #{name_or_path} locally or in
remote repository." unless spec
+ end
else fail "First argument must be Gem name or File task."
end
Modified: incubator/buildr/trunk/spec/addon_spec.rb
URL:
http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/addon_spec.rb?rev=639925&r1=639924&r2=639925&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/addon_spec.rb (original)
+++ incubator/buildr/trunk/spec/addon_spec.rb Fri Mar 21 16:59:34 2008
@@ -101,6 +101,13 @@
lambda { addon 'foobar', '~> 1' }.should change { spec =
Gem.loaded_specs['foobar'] and spec.full_name }.to('foobar-1.2')
end
+ it 'should support array of version matches' do
+ ['1.0', '1.1', '1.2'].each do |version|
+ available 'foobar', version
+ end
+ lambda { addon 'foobar', ['> 1.0', '< 1.2'] }.should change { spec =
Gem.loaded_specs['foobar'] and spec.full_name }.to('foobar-1.1')
+ end
+
it 'should complain if no version matches requirement' do
available 'foobar', '1.0'
lambda { addon 'foobar', '2.0' }.should raise_error(Gem::LoadError, /could
not find/i)
@@ -113,6 +120,14 @@
lambda { addon 'foobar', '2.0' }.should raise_error(Exception, /can't
activate/)
end
+ it 'should not upgrade if compatible version available in local repository'
do
+ available 'foobar', '1.0'
+ addon 'foobar', '1.0'
+ available 'foobar', '2.0'
+ addon 'foobar', '1.0'
+ Gem.loaded_specs['foobar'].full_name.should eql('foobar-1.0')
+ end
+
it 'should complain if gem not in remote repository' do
lambda { addon 'foobar', '1.1' }.should raise_error(Gem::LoadError, /could
not find foobar/i)
end
@@ -134,6 +149,15 @@
addon 'foobar'
end.should_not change { $loaded }
lambda { require 'extra/foobar.rb' }.should change { $loaded }.to(true)
+ end
+
+ it 'should require files only once' do
+ write 'lib/foobar.rb', '$loaded = $loaded.to_i + 1'
+ available 'foobar', '1.0'
+ lambda do
+ addon 'foobar'
+ addon 'foobar'
+ end.should change { $loaded }.to(1)
end
it 'should import all .rake files in tasks directory' do