lib/rubyfromexcel.rb in rubyfromexcel-0.0.4 vs lib/rubyfromexcel.rb in rubyfromexcel-0.0.5

- old
+ new

@@ -22,59 +22,92 @@ attr_accessor :target_ruby_directory attr_accessor :workbook attr_accessor :skip_tests attr_accessor :prune_except_output_sheets attr_accessor :convert_independent_of_input_sheets + attr_accessor :checkpoint_directory + attr_accessor :stage + attr_accessor :debug_dont_write_checkpoint_after_stage def initialize(&block) instance_eval(&block) if block + load_from_checkpoint end def workbook_filename File.join(source_excel_directory,'xl','workbook.xml') end - def start! - reset_global_classes + def start!(starting_stage = nil) + self.stage = starting_stage || self.stage || 0 - time "Preparing destination folder..." do - prepare_destination_folder - end + checkpoint 0 do + reset_global_classes + + time "Preparing destination folder..." do + prepare_destination_folder + end - time "Loading..." do - self.workbook = Workbook.new(workbook_filename) + time "Loading..." do + self.workbook = Workbook.new(workbook_filename) + end end - - if prune_except_output_sheets - time "Pruning..." do - workbook.prune_cells_not_needed_for_output_sheets(*prune_except_output_sheets) - workbook.convert_cells_to_values_when_independent_of_input_sheets(*convert_independent_of_input_sheets) + + time "Pruning..." do + + checkpoint 1 do + if prune_except_output_sheets + workbook.prune_cells_not_needed_for_output_sheets(*prune_except_output_sheets) + end end + + checkpoint 2 do + if prune_except_output_sheets + workbook.convert_cells_to_values_when_independent_of_input_sheets(*convert_independent_of_input_sheets) + end + end + end time "Workbook contains #{workbook.worksheets.size} sheets:\n" do + + checkpoint 3 do + puts "0) Generating ruby for the workbook" + write "spreadsheet.rb" do + workbook.to_ruby + end + end - puts "0) Generating ruby for the workbook" - write workbook.to_ruby, :to, "spreadsheet.rb" - - i = 0 - workbook.worksheets.each do |variable_name, worksheet| - time "#{i+=1}) Generating ruby for #{variable_name}..." do - print 'ruby...' - write worksheet.to_ruby, :to, 'sheets', "#{variable_name}.rb" - unless skip_tests - print 'test...' - write worksheet.to_test, :to, 'specs',"#{variable_name}_rspec.rb" + checkpoint 4 do + i = 0 + workbook.worksheets.each do |variable_name, worksheet| + time "#{i+=1}) Generating ruby for #{variable_name}..." do + write 'sheets', "#{variable_name}.rb" do + worksheet.to_ruby + end end - # worksheet.nil_memory_consuming_variables! end end - + + checkpoint 5 do + unless skip_tests + i = 0 + workbook.worksheets.each do |variable_name, worksheet| + time "#{i+=1}) Generating spec for #{variable_name}..." do + write 'specs',"#{variable_name}_rspec.rb" do + worksheet.to_test + end + end + end + end # skip tests + end # 5 + end + unless skip_tests puts "Running tests of generated files" - puts `spec -fo #{File.join(target_ruby_directory,'specs',"*")}` + puts `rspec -fp #{File.join(target_ruby_directory,'specs',"*")}` end end # FIXME: Urgh. Global variables. Need to eliminate these! def reset_global_classes @@ -85,13 +118,67 @@ def prepare_destination_folder FileUtils.mkpath(File.join(target_ruby_directory,'specs')) FileUtils.mkpath(File.join(target_ruby_directory,'sheets')) end - def write(thing,to,*filenames) - File.open(File.join(target_ruby_directory,*filenames),'w') do |f| - f.puts thing.to_s + def write(*filenames) + target_filename = File.join(target_ruby_directory,*filenames) + if checkpoint_directory && !debug_dont_write_checkpoint_after_stage && File.exists?(target_filename) + print "skipping #{File.basename(target_filename)}, already exists and checkpoints are on..." + return nil end + File.open(target_filename,'w') do |f| + f.puts yield.to_s + end + end + + def checkpoint(checkpoint_number) + puts + if self.stage > checkpoint_number + puts "Stage #{checkpoint_number} already completed, skipping..." + return + else + puts "Stage #{checkpoint_number}" + end + yield + save_checkpoint if checkpoint_directory # Then create a check point + self.stage = checkpoint_number + 1 + end + + def save_checkpoint + if debug_dont_write_checkpoint_after_stage && (self.stage > debug_dont_write_checkpoint_after_stage) + puts "Debug mode: Not writing checkpoint for stage #{checkpoint_number}" + return + else + puts "Writing checkpoint for stage #{self.stage}" + FileUtils.mkpath(checkpoint_directory) + objects_to_dump = [self.stage,self.workbook,SheetNames.instance.to_hash,SharedStrings.instance.to_a] + File.open(checkpoint_filename,'w') { |f| f.puts Marshal.dump(objects_to_dump) } + end + end + + def load_from_checkpoint + unless checkpoint_directory + puts "No checkpoint directory given" + return false + end + checkpoint_filenames = Dir.entries(checkpoint_directory) + highest_stage_checkpoint = checkpoint_filenames.map { |filename| filename =~ /checkpoint(\d+)/ ? $1.to_i : 0 }.max + checkpoint_to_open = File.join(checkpoint_directory,"checkpoint#{highest_stage_checkpoint}.marshal") + unless File.exists?(checkpoint_to_open) + puts "No checkpoint file found" + return false + end + dumped_objects = Marshal.load(File.open(checkpoint_to_open)) + self.stage = dumped_objects.shift + 1 + self.workbook = dumped_objects.shift + SheetNames.instance.replace(dumped_objects.shift) + SharedStrings.instance.replace(dumped_objects.shift) + puts "Stage #{self.stage-1} checkpoint found and loaded." + end + + def checkpoint_filename + File.join(checkpoint_directory,"checkpoint#{self.stage}.marshal") end def time(message) print message STDOUT.flush \ No newline at end of file