commit f4aab4ba1dfa0dbc7f52925a3b58f39b169eb778
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Wed Jul 29 01:05:16 2009 +0200

    [evol] improved the 'tree' command a bit (limit to subtree, and allow listing all objects)

diff --git a/bin/shadowwalker b/bin/shadowwalker
index 3e2855b..6ceee51 100755
--- a/bin/shadowwalker
+++ b/bin/shadowwalker
@@ -93,6 +93,32 @@ class Command < CmdParse::Command
       super
     end
   end
+
+  protected
+
+  def params_shift_location(args)
+    location = args.shift
+    if location =~ /^([a-zA-Z]+)\/(.+)$/
+      loc_obj_hdl = $1
+      loc_item_hdl = $2
+    else
+      STDERR.puts "syntax error: bad location"
+      exit 1
+    end
+    loc_obj_klass = $ldapctl.find_klass(loc_obj_hdl)
+    if loc_obj_klass.nil?
+      STDERR.puts "No such location object '#{loc_obj_hdl}'."
+      exit 2
+    end
+    begin
+      loc_item = loc_obj_klass.find(loc_item_hdl)
+    rescue ActiveLdap::EntryNotFound
+      STDERR.puts "No such item '#{loc_obj_hdl}/#{loc_item_hdl}'"
+      exit 2
+    end
+
+    [loc_obj_klass, loc_item]
+  end
 end
 
 class ListCommand < Command
@@ -294,37 +320,58 @@ class TreeCommand < Command
 
     self.short_desc = "show skeleton items tree"
     self.usages_params = [
-                          ""
+                          "[<location>]"
                           ]
+    self.options = CmdParse::OptionParserWrapper.new do |opt|
+      opt.on( '-a', '--all', 'Display all objects in the tree.' ) { $program_options[:tree_all_objects] = true }
+    end
   end
 
   def execute (args)
     puts "Tree:"
 
-    base_dn = ActiveLdap::DistinguishedName.parse(LdapObject.base)
+    search_base = nil
+    unless args.empty?
+      loc_obj_klass, loc_item = params_shift_location(args)
+      search_base = loc_item.dn
+    end
 
-    gconfig = $ldapctl.get_global_config()
-    if gconfig.has_key?(:tree_objects)
-      tree = {}
+    if $program_options[:tree_all_objects]
+      dn_list = ActiveLdap::Base.search(:base => search_base, :scope => :sub, :attributes => ['']).collect do |entry|
+        ActiveLdap::DistinguishedName.parse(entry.first)
+      end
+    else
+      dn_list = []
+      gconfig = $ldapctl.get_global_config()
 
-      gconfig[:tree_objects].each do |obj_hdl|
+      (gconfig[:tree_objects] || []).each do |obj_hdl|
         obj_klass = $ldapctl.find_klass(obj_hdl)
-        raise "object '#{obj_hdl}' not defined" unless obj_klass
-
-        obj_klass.find(:all).each do |obj|
-          ptree = tree
-          pdn = nil
-          (obj.dn_obj - base_dn).to_s.split(',').reverse.each do |pdn|
-            ptree[pdn] = {} unless ptree.has_key?(pdn)
-            ptree = ptree[pdn]
-          end
-          ptree = nil
+        unless obj_klass
+          STDERR.puts "Location object '#{obj_hdl}' not defined."
+          exit 2
+        end
+
+        obj_klass.find(:all, :base => search_base, :scope => :sub).each do |obj|
+          dn_list << obj.dn_obj
         end
       end
-      tree = {base_dn => tree}
+    end
+
+    base_dn = ActiveLdap::DistinguishedName.parse(LdapObject.base)
 
-      Display.display_hash_tree(tree, 0)
+    tree = {}
+    dn_list.each do |dn|
+      ptree = tree
+      pdn = nil
+      (dn - base_dn).to_s.split(',').reverse.each do |pdn|
+        ptree[pdn] = {} unless ptree.has_key?(pdn)
+        ptree = ptree[pdn]
+      end
+      ptree = nil
     end
+    tree = {base_dn => tree}
+
+    Display.display_hash_tree(tree, 0)
   end
 end
 cmdparser.add_command(TreeCommand.new)
@@ -611,25 +658,7 @@ class CreateCommand < Command
 
     item_hdl = args.shift
 
-    location = args.shift
-    if location =~ /^([a-zA-Z]+)\/(.+)$/
-      loc_obj_hdl = $1
-      loc_item_hdl = $2
-    else
-      STDERR.puts "syntax error: bad location"
-      exit 1
-    end
-    loc_obj_klass = $ldapctl.find_klass(loc_obj_hdl)
-    if loc_obj_klass.nil?
-      STDERR.puts "No such location object '#{loc_obj_hdl}'."
-      exit 2
-    end
-    begin
-      loc_item = loc_obj_klass.find(loc_item_hdl)
-    rescue ActiveLdap::EntryNotFound
-      STDERR.puts "No such item '#{loc_obj_hdl}/#{loc_item_hdl}'"
-      exit 2
-    end
+    loc_obj_klass, loc_item = params_shift_location(args)
 
     item = obj_klass.new(item_hdl)
     item.base = loc_item.dn_obj - obj_klass.base_obj
