<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -116,6 +116,7 @@ module Sprinkle
         @provides = metadata[:provides]
         @dependencies = []
         @recommends = []
+        @optional = []
         @verifications = []
         self.instance_eval &amp;block
       end
@@ -233,12 +234,17 @@ module Sprinkle
         @recommends.flatten!
       end
 
+      def optional(*packages)
+        @optional &lt;&lt; packages
+        @optional.flatten!
+      end
+
       def tree(depth = 1, &amp;block)
         packages = []
 
         @recommends.each do |dep|
           package = PACKAGES[dep]
-          next unless package # skip missing recommended packages as they can be optional
+          next unless package # skip missing recommended packages as they're allowed to not exist
           block.call(self, package, depth) if block
           packages &lt;&lt; package.tree(depth + 1, &amp;block)
         end
@@ -253,6 +259,15 @@ module Sprinkle
         end
 
         packages &lt;&lt; self
+
+        @optional.each do |dep|
+          package = PACKAGES[dep]
+          next unless package # skip missing optional packages as they're allow to not exist
+          block.call(self, package, depth) if block
+          packages &lt;&lt; package.tree(depth + 1, &amp;block)
+        end
+
+        packages
       end
 
       def to_s; @name; end</diff>
      <filename>lib/sprinkle/package.rb</filename>
    </modified>
    <modified>
      <diff>@@ -83,6 +83,13 @@ CODE
       pkg.recommends.should == [:webserver, :database]
     end
 
+    it 'should optionally accept optional dependencies' do
+      pkg = package @name do
+        optional :webserver_configuration, :database_configuration
+      end
+      pkg.optional.should == [:webserver_configuration, :database_configuration]
+    end
+
     it 'should optionally define a virtual package implementation' do
       pkg = package @name, :provides =&gt; :database do; end
       pkg.provides.should == :database
@@ -338,6 +345,7 @@ CODE
       @b = package :b do; requires :c; end
       @c = package :c do; recommends :d; end
       @d = package :d do; end
+      @e = package :e do; optional :d; end
     end
 
     it 'should be able to return a dependency hierarchy tree' do
@@ -345,12 +353,25 @@ CODE
       @b.tree.flatten.should == [ @d, @c, @b ]
       @c.tree.flatten.should == [ @d, @c ]
       @d.tree.flatten.should == [ @d ]
+      @e.tree.flatten.should == [ @e, @d ]
     end
 
     describe 'with missing recommendations' do
 
       before do
-        @d.recommends :e
+        @d.recommends :z
+      end
+
+      it 'should ignore missing recommendations' do
+        @d.tree.flatten.should == [ @d ]
+      end
+
+    end
+
+    describe 'with missing optional packages' do
+
+      before do
+        @d.optional :z
       end
 
       it 'should ignore missing recommendations' do</diff>
      <filename>spec/sprinkle/package_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>3fdb7eb754d648721d9255935ddf262fd2aea03f</id>
    </parent>
  </parents>
  <author>
    <name>Marcus Crafter</name>
    <email>crafterm@redartisan.com</email>
  </author>
  <url>http://github.com/crafterm/sprinkle/commit/13bdeb067e5a5f0236d06f7800143ba67b6cae1d</url>
  <id>13bdeb067e5a5f0236d06f7800143ba67b6cae1d</id>
  <committed-date>2009-07-24T20:14:42-07:00</committed-date>
  <authored-date>2009-07-24T00:07:51-07:00</authored-date>
  <message>Add support for optional packages, that are installed if present, after the main package has been installed. Update specs to validate.</message>
  <tree>d5447b913786f5e7dfb1e9be1718b3c5b0217a14</tree>
  <committer>
    <name>Marcus Crafter</name>
    <email>crafterm@redartisan.com</email>
  </committer>
</commit>
