commit bbb82941c2fdab4ecf351b8a2f2868868660df2f
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Thu Jul 23 02:54:37 2009 +0200

    [evol] code cleanup, and allowed pluralized version of object name in 'list' command

diff --git a/bin/shadowwalker b/bin/shadowwalker
index 336c067..b0137ee 100755
--- a/bin/shadowwalker
+++ b/bin/shadowwalker
@@ -22,9 +22,12 @@
 $: << File.join(File.dirname(__FILE__), "..", "lib")
 
 require 'ldap_shadows'
+require 'ldap_shadows/display_utils'
 require 'yaml'
 require 'cmdparse2'
 
+include LdapShadows
+
 config_str = IO.read(File.join(LdapShadows::Config::CFG_DIR, "test.conf"))
 config = YAML.load(config_str)
 config_str_prv_filelist = [
@@ -41,16 +44,18 @@ end
 config.recursive_symbolize_keys!
 ActiveLdap::Base.setup_connection(config[:ldap])
 
+$program_options = {}
+
 cmdparser = CmdParse::CommandParser.new(true)
-cmdparser.banner = LdapShadows::PRODUCT
+cmdparser.banner = PRODUCT
 cmdparser.program_name = File.basename(__FILE__)
-cmdparser.program_version = LdapShadows::VERSION.split(".")
+cmdparser.program_version = VERSION.split(".")
 
 cmdparser.options = CmdParse::OptionParserWrapper.new do |opt|
   opt.separator "Global options:"
-  opt.on("--debug", "Output debug info without being formated") {|t| $debug_opt = true }
-  opt.on("--expert", "Output extra info for expert users") {|t| $expert_opt = true }
-  opt.on("--handles", "Output with handles (objects/field/... keys used for manipulations)") {|t| $handles_opt = true }
+  opt.on("--debug", "Output debug info without being formated") {|t| $program_options[:debug] = true }
+  opt.on("--expert", "Output extra info for expert users") {|t| $program_options[:expert] = true }
+  opt.on("--handles", "Output with handles (objects/field/... keys used for manipulations)") {|t| $program_options[:handles] = true }
 end
 
 cmdparser.add_command(CmdParse::HelpCommand.new)
@@ -59,7 +64,7 @@ cmdparser.add_command(CmdParse::VersionCommand.new)
 I18n.load_path += Dir[File.join(LdapShadows::Config::DATA_DIR, "*.yml")]
 I18n.default_locale = :en
 
-ldapctl = LdapShadows::Controller.new
+ldapctl = Controller.new
 ldapctl.set_global_config(config[:presentation])
 config[:aspects].each_pair do |aspect_name, aspect_data|
   ldapctl.set_aspect(aspect_name, aspect_data)
@@ -69,6 +74,10 @@ config[:objects].each_pair do |obj_name, obj_data|
 end
 ldapctl.load_relations
 
+def translate_object_name(obj_hdl)
+  I18n.t(obj_hdl, :scope => 'objects', :default => "Object '#{obj_hdl}'")
+end
+
 cmd = CmdParse::Command.new('list', false)
 cmd.short_desc = "list objects"
 cmd.set_execution_block do |args|
@@ -77,45 +86,41 @@ cmd.set_execution_block do |args|
     exit 1
   end
 
-  obj_hdl = args[0]
+  obj_hdl = args[0].singularize
   obj_klass = ldapctl.find_klass(obj_hdl)
   if obj_klass.nil?
     STDERR.puts "No such object '#{obj_hdl}'."
     exit 2
   end
 
-  obj_human_name = I18n.t(obj_hdl, :scope => 'objects', :default => "Object '#{obj_hdl}'")
+  obj_human_name = translate_object_name(obj_hdl)
   puts "=== List of #{obj_human_name.pluralize} ==="
   obj_klass.find(:all).each do |obj|
     str = obj.human_name
-    str += " [#{obj.name}]" if $handles_opt
+    str += " [#{obj.name}]" if $program_options[:handles]
     str += ": #{obj.description}" unless obj.description.empty?
     puts str
   end
 end
 cmdparser.add_command(cmd)
 
-def translate_data_key(name)
-  if name.index(":")
-    type, key = name.split(":")
+def translate_field_name(field_name)
+  if field_name.index(":")
+    type, key = field_name.split(":")
     case type
     when 'rel'
-      I18n.t(key, :scope => 'relations', :default => name)
+      I18n.t(key, :scope => 'relations', :default => field_name)
     else
       raise "Cannot translate unknown data key type"
     end
   else
-    att = ActiveLdap::Base.schema.attribute(name)
+    att = ActiveLdap::Base.schema.attribute(field_name)
     I18n.t(att.human_attribute_name, :scope => 'attribute_types', :default => att.human_attribute_description)
   end
 end
 
-def display_data(attr_data)
-  attr_data.each_pair do |key, val|
-    field_name = translate_data_key(key)
-    field_name += " [#{key}]" if $handles_opt
-    puts field_name + ": " + (val.is_a?(Array) ? val.sort.collect{|v| v.to_s }.join(", ") : val.to_s)
-  end
+def translate_aspect_name(aspect_name)
+  I18n.t(aspect_name, :scope => 'aspects', :default => "Aspect '#{aspect_name}'")
 end
 
 cmd = CmdParse::Command.new('show', false)
@@ -145,56 +150,16 @@ cmd.set_execution_block do |args|
     exit 2
   end
 
-  obj_human_name = I18n.t(obj_hdl, :scope => 'objects', :default => "Object '#{obj_hdl}'")
-  name = item.human_name
-  name += " [#{item.name}]" if $handles_opt
-  puts "=== #{obj_human_name}: #{name} ==="
-
-  if $debug_opt
-    puts item.to_s
-    puts "--- Detected Info ---"
-    puts "aspects: " + item.aspects.sort.join(", ")
-
-    puts "--- Family ---"
-    puts "parent: " + item.family_parent_dn.to_s
-    puts "siblings: " + item.family_siblings_dn.join(", ")
-    puts "children: " + item.family_children_dn.join(", ")
-
-    puts "--- Relations ---"
-    item.relations.each do |rel|
-      puts "#{rel}: " + item.send(rel).collect{|g| g.name }.join(", ")
-    end
-  else
-    obj_info, obj_aspects = item.organized_data(:expert => $expert_opt, :skip_binary => true)
-
-    display_data(obj_info)
-
-    obj_aspects.each_pair do |aspect_name, aspect_data|
-      aspect_display_name = I18n.t(aspect_name, :scope => 'aspects', :default => "Aspect '#{aspect_name}'")
-      puts "--- #{aspect_display_name} ---"
-      display_data(aspect_data)
-    end
-  end
+  Display.display_item(item, $program_options)
 end
 cmdparser.add_command(cmd)
 
-def display_tree(tree, level)
-  tree.keys.sort.each do |key|
-    str = ""
-    str += " " + "|    " * (level -1) + "+-- " if level > 0
-    str += "<#{key}>"
-    puts str
-
-    display_tree(tree[key], level + 1) if tree[key]
-  end
-end
-
 cmd = CmdParse::Command.new('tree', false)
 cmd.short_desc = "show skeleton objects tree"
 cmd.set_execution_block do |args|
   puts "Tree:"
 
-  base_dn = ActiveLdap::DistinguishedName.parse(LdapShadows::LdapObject.base)
+  base_dn = ActiveLdap::DistinguishedName.parse(LdapObject.base)
 
   gconfig = ldapctl.get_global_config()
   if gconfig.has_key?(:tree_objects)
@@ -216,7 +181,7 @@ cmd.set_execution_block do |args|
     end
     tree = {base_dn => tree}
 
-    display_tree(tree, 0)
+    Display.display_hash_tree(tree, 0)
   end
 end
 cmdparser.add_command(cmd)
diff --git a/lib/ldap_shadows/controller.rb b/lib/ldap_shadows/controller.rb
index 3526828..d90f72e 100755
--- a/lib/ldap_shadows/controller.rb
+++ b/lib/ldap_shadows/controller.rb
@@ -62,6 +62,7 @@ module LdapShadows
 
       # configure class
       klass = find_klass(obj_name)
+      klass.handle = obj_name
       klass.presentation = obj_def[:presentation]
       klass.mapper = self
       klass.ldap_mapping obj_mapping.reject {|key, val| not ActiveLdap::Base::VALID_LDAP_MAPPING_OPTIONS.include?(key) }
diff --git a/lib/ldap_shadows/display_utils.rb b/lib/ldap_shadows/display_utils.rb
new file mode 100644
index 0000000..8960604
--- /dev/null
+++ b/lib/ldap_shadows/display_utils.rb
@@ -0,0 +1,55 @@
+
+module LdapShadows
+  module Display
+    def self.display_fields(attr_data, options = {})
+      attr_data.each_pair do |key, val|
+        field_name = translate_field_name(key)
+        field_name += " [#{key}]" if options[:handles]
+        puts field_name + ": " + (val.is_a?(Array) ? val.sort.collect{|v| v.to_s }.join(", ") : val.to_s)
+      end
+    end
+
+    def self.display_item(item, options = {})
+      obj_human_name = translate_object_name(item.handle)
+      name = item.human_name
+      name += " [#{item.name}]" if options[:handles]
+      puts "=== #{obj_human_name}: #{name} ==="
+
+      if options[:debug]
+        puts item.to_s
+        puts "--- Detected Info ---"
+        puts "aspects: " + item.aspects.sort.join(", ")
+
+        puts "--- Family ---"
+        puts "parent: " + item.family_parent_dn.to_s
+        puts "siblings: " + item.family_siblings_dn.join(", ")
+        puts "children: " + item.family_children_dn.join(", ")
+
+        puts "--- Relations ---"
+        item.relations.each do |rel|
+          puts "#{rel}: " + item.send(rel).collect{|g| g.name }.join(", ")
+        end
+      else
+        obj_info, obj_aspects = item.organized_data(:expert => options[:expert], :skip_binary => true)
+
+        display_fields(obj_info, options)
+
+        obj_aspects.each_pair do |aspect_name, aspect_data|
+          puts "--- #{translate_aspect_name(aspect_name)} ---"
+          display_fields(aspect_data, options)
+        end
+      end
+    end
+
+    def self.display_hash_tree(tree, level)
+      tree.keys.sort.each do |key|
+        str = ""
+        str += " " + "|    " * (level -1) + "+-- " if level > 0
+        str += "<#{key}>"
+        puts str
+
+        display_hash_tree(tree[key], level + 1) if tree[key]
+      end
+    end
+  end
+end
diff --git a/lib/ldap_shadows/object.rb b/lib/ldap_shadows/object.rb
index 1856174..7fe36d3 100755
--- a/lib/ldap_shadows/object.rb
+++ b/lib/ldap_shadows/object.rb
@@ -19,7 +19,7 @@
 
 module LdapShadows
   class LdapObject < ActiveLdap::Base
-    class_inheritable_accessor :presentation, :mapper
+    class_inheritable_accessor :handle, :presentation, :mapper
 
     ldap_mapping :prefix => '', :classes => ['top'], :scope => :sub
 
