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


Reply via email to