<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -2,38 +2,146 @@
 
 Simple API for importing csv files.
 
-== Usage
+== Defining importers
 
-define custom importers by including simple_importer
-  class CrazyImporter
-    include SimpleImporter
+The basic importer has a name, file, and a foreach block.
 
-    file 'data.csv'
-    callbacks true
+  importer :items do
+    file 'items.csv'
+
+    foreach do |row|
+      Item.create(:name =&gt; row[:name])
+    end
+  end
+
+simple_importer uses fastercsv, which replaces the csv standard lib in ruby1.9. Importers have configuration options that match those of fastercsv. The foreach block is called for each row in the csv file. The argument passed into the foreach block is a fastercsv row created with the specified configuration options.
+
+  importer :items do
+    file 'items.csv'
+
+    # all fastercsv options are supported
+    headers false
+    converters :numeric
+    # etc..
+
+    foreach do |row|
+      Item.create(:name =&gt; row[:name])
+    end
+  end
+
+Importers have a default configuration that matches the following importer.
+
+  importer :items do
+    file 'items.csv'
+
+    # default configuration
+    col_sep &quot;,&quot;
+    row_sep :auto
+    quote_char '&quot;'
+    field_size_limit nil
+    converters :all
+    unconverted_fields nil
     headers true
+    return_headers false
     header_converters :symbol
-    converters :all
+    skip_blanks false
+    force_quotes false
+
+    foreach do |row|
+      Item.create(:name =&gt; row[:name])
+    end
+  end
+
+== Before callback
 
-    before_import :delete_all
+Define before_filter-style callbacks in the form of the before block. This block is run once before the importer run.
+
+  importer :items do
+    file 'items.csv'
+
+    before do
+      Item.delete_all
+    end
 
     foreach do |row|
+      Item.create(:name =&gt; row[:name])
     end
+  end
+
+== File processing
+
+Passing an array of file paths to the file configuration field will process all the rows in each file.
 
-    def delete_all
+  importer :items do
+    file Dir.glob(&quot;data/*.csv&quot;)
+
+    foreach do |row|
+      Item.create(:name =&gt; row[:name])
+    end
+  end
+
+Use the foreach_file block to add per-file behavior.
+
+  importer :items do
+    file Dir.glob(&quot;data/*.csv&quot;)
+
+    foreach_file do |file|
+      List.create(:name =&gt; File.basename(file, &quot;.csv&quot;))
+    end
+
+    foreach do |row|
+      Item.create(:name =&gt; row[:name])
+    end
+  end
+
+Nest the foreach block to give your row processing block access to foreach_file block variables.
+
+  importer :items do
+    file Dir.glob(&quot;data/*.csv&quot;)
+
+    foreach_file do |file|
+      list = List.create(:name =&gt; File.basename(file, &quot;.csv&quot;))
+
+      foreach do |row|
+        Item.create(:name =&gt; row[:name], :list =&gt; list)
+      end
     end
   end
 
-run your importers
-  CrazyImporter.run
+== Loading and running importers
+
+simple_importer provides a method that will find and load importer definitions in importers, lib/importers, and app/importers directories.
 
-== TODO
+  # importer definition is in lib/importers/item.rb
+  SimpleImporter.find_importers
+
+SimpleImporter has a collection of importers and each importer can be run once it has been loaded.
+
+  # the following will fire off the actual importers
+  SimpleImporter.importers.each do |importer|
+    importer.run
+  end
 
-find files automatically
-rake tasks generated automatically
+== Rake tasks and autoloaded importers
+
+simple_importer provides rake tasks to run importers individually or all at once.
+
+  # add this to your rakefile
+  # lib/tasks/simple_importer.rake is a good place in your rails app
+  require 'simple_importer/tasks'
+
+rake -T simple_importer will show a rake task for each importer as well as an import task which runs all of the importers. Descriptions defined in the importer will be used for the rake task description.
+
+  importer :items do
+    file 'items.csv'
+    desc 'Import all of the cool items'
+
+    ...
+  end
 
 == Requirements
 
-* fast_csv (if you are not using ruby 1.9)
+* fastercsv (if you are not using ruby 1.9)
 
 == Note on Patches/Pull Requests 
 </diff>
      <filename>README.rdoc</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,6 @@ begin
     gem.email = &quot;gotascii@gmail.com&quot;
     gem.homepage = &quot;http://github.com/vigetlabs/simple_importer&quot;
     gem.authors = [&quot;Justin Marney&quot;]
-    gem.add_development_dependency &quot;thoughtbot-shoulda&quot;, &quot;&gt;= 0&quot;
     # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
   end
 rescue LoadError</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,10 @@
-require 'csv'
+require &quot;csv&quot;
 
-# require 'lib/simple_importer'
-# SimpleImporter.find_importers
-# SimpleImporter[:crazy].run
+if CSV.const_defined? :Reader
+  require 'fastercsv'
+  Object.send(:remove_const, :CSV)
+  CSV = FasterCSV
+end
 
 module SimpleImporter
   def self.included(base)
@@ -15,7 +17,7 @@ module SimpleImporter
       METH
     end
 
-    [:before, :foreach].each do |meth|
+    [:before, :foreach, :foreach_file].each do |meth|
       base.class_eval &lt;&lt;-METH
         def #{meth}(&amp;block)
           config[:#{meth}] = block if block_given?
@@ -23,6 +25,10 @@ module SimpleImporter
         end
       METH
     end
+    
+    base.class_eval do
+      attr_accessor :name
+    end
   end
 
   def self.importer_paths
@@ -43,19 +49,19 @@ module SimpleImporter
   end
 
   def self.config_meths
-    csv_config_meths + [:file, :callbacks]
+    csv_config_meths + [:file, :callbacks, :desc]
   end
 
   def self.importers
-    @importers ||= {}
+    @importers ||= []
   end
 
   def self.importer(name, &amp;block)
-    importers[name] = Importer.new(&amp;block)
+    importers &lt;&lt; Importer.new(name, &amp;block)
   end
 
   def self.[](name)
-    importers[name]
+    importers.select{|i| i.name == name}.first
   end
 
   def config
@@ -63,7 +69,8 @@ module SimpleImporter
       :callbacks =&gt; true,
       :headers =&gt; true,
       :header_converters =&gt; :symbol,
-      :converters =&gt; :all
+      :converters =&gt; :all,
+      :desc =&gt; 'a simple_import importer'
     }
   end
 
@@ -73,7 +80,10 @@ module SimpleImporter
 
   def run
     run_callbacks
-    CSV.foreach(file, csv_config, &amp;foreach)
+    [file].flatten.each do |f|
+      foreach_file.call(f) if foreach_file
+      CSV.foreach(f, csv_config, &amp;foreach) if foreach
+    end
   end
 
   def run_callbacks
@@ -83,7 +93,8 @@ module SimpleImporter
   class Importer
     include SimpleImporter
 
-    def initialize(&amp;block)
+    def initialize(name, &amp;block)
+      self.name = name
       instance_eval(&amp;block)
     end
   end</diff>
      <filename>lib/simple_importer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,24 @@
 namespace :simple_importer do
-  desc &quot;find SimpleImporter&quot;
-  task :find do
+  def importers
     require 'simple_importer'
-    puts SimpleImporter
+    SimpleImporter.find_importers
+    SimpleImporter.importers
+  end
+
+  importers.each do |i|
+    desc i.desc
+    task i.name do
+      Rake::Task[:environment].invoke if Rake::Task.task_defined?(:environment)
+      puts &quot;Importing #{i.name}&quot;
+      i.run
+      puts &quot;Finished importing #{i.name}&quot;
+    end
+  end
+
+  desc &quot;run all importers&quot;
+  task :import do
+    importers.each do |i|
+      Rake::Task[&quot;simple_importer:#{i.name}&quot;].invoke
+    end
   end
 end
\ No newline at end of file</diff>
      <filename>lib/simple_importer/tasks/simple_importer.rake</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,6 @@ begin
     gem.email = &quot;gotascii@gmail.com&quot;
     gem.homepage = &quot;http://github.com/gotascii/simple_importer&quot;
     gem.authors = [&quot;gotascii&quot;]
-    gem.add_development_dependency &quot;thoughtbot-shoulda&quot;, &quot;&gt;= 0&quot;
     # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
   end
 rescue LoadError</diff>
      <filename>simple_importer.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -11,19 +11,18 @@ class SimpleImporterTest &lt; Test::Unit::TestCase
     end
 
     should &quot;have an importers hash field&quot; do
-      SimpleImporter.importers.should == {}
+      SimpleImporter.importers.should == []
     end
 
     should &quot;create a new importer&quot; do
-      block = lambda{ 'omg' }
-      SimpleImporter::Importer.expects(:new).with(&amp;block)
-      SimpleImporter.importer(:bob, &amp;block)
+      SimpleImporter::Importer.expects(:new).with(:bob)
+      SimpleImporter.importer(:bob)
     end
 
     should &quot;add new importer to importers&quot; do
       SimpleImporter::Importer.stubs(:new).returns('hi')
       SimpleImporter.importer(:bob)
-      SimpleImporter.importers[:bob].should == 'hi'
+      SimpleImporter.importers.should == ['hi']
     end
 
     should &quot;look in importer, app/importers, and lib/importers for importers&quot; do
@@ -36,12 +35,13 @@ class SimpleImporterTest &lt; Test::Unit::TestCase
 
     should &quot;return csv_config_meths plus file and callbacks for config_meths&quot; do
       SimpleImporter.stubs(:csv_config_meths).returns([:yo])
-      SimpleImporter.config_meths.should == [:yo, :file, :callbacks]
+      SimpleImporter.config_meths.should == [:yo, :file, :callbacks, :desc]
     end
 
-    should &quot;forward [] to importers&quot; do
-      SimpleImporter.importers.expects(:[]).with(:omg).returns('hey')
-      SimpleImporter[:omg].should == 'hey'
+    should &quot;return first importer whos name matches arg for []&quot; do
+      importer = stub(:name =&gt; :omg)
+      SimpleImporter.stubs(:importers).returns([importer])
+      SimpleImporter[:omg].should == importer
     end
   end
 
@@ -131,6 +131,14 @@ class SimpleImporterTest &lt; Test::Unit::TestCase
       CSV.expects(:foreach).with('file', 'csv_config')
       @importer.run
     end
+
+    should &quot;call CSV.foreach with each file if file is an array&quot; do
+      @importer.stubs(:file).returns(['file1', 'file2'])
+      @importer.stubs(:csv_config).returns('csv_config')
+      CSV.expects(:foreach).with('file1', 'csv_config')
+      CSV.expects(:foreach).with('file2', 'csv_config')
+      @importer.run
+    end
   end
 
   context &quot;The Importer class&quot; do
@@ -140,7 +148,7 @@ class SimpleImporterTest &lt; Test::Unit::TestCase
 
     should &quot;instance eval block on initialize&quot; do
       SimpleImporter::Importer.any_instance.expects(:bobo)
-      SimpleImporter::Importer.new do
+      SimpleImporter::Importer.new(:hi) do
         bobo
       end
     end</diff>
      <filename>test/test_simple_importer.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>bac421afec835186bfc2231ed8901d3340395632</id>
    </parent>
  </parents>
  <author>
    <name>Justin Marney</name>
    <email>gotascii@gmail.com</email>
  </author>
  <url>http://github.com/vigetlabs/simple_importer/commit/000aaf2b3e6259c68c6bf4b069dccf8dc898a933</url>
  <id>000aaf2b3e6259c68c6bf4b069dccf8dc898a933</id>
  <committed-date>2009-10-22T14:03:55-07:00</committed-date>
  <authored-date>2009-10-22T14:03:55-07:00</authored-date>
  <message>documentation and some polish, sausage</message>
  <tree>411f9170eabb54927f968d769f6d8a236fd24e89</tree>
  <committer>
    <name>Justin Marney</name>
    <email>gotascii@gmail.com</email>
  </committer>
</commit>
