Skip to content

Instantly share code, notes, and snippets.

@morrifeldman
Created November 11, 2012 22:35
Show Gist options
  • Save morrifeldman/4056549 to your computer and use it in GitHub Desktop.
Save morrifeldman/4056549 to your computer and use it in GitHub Desktop.
Simple rake extension to wrap a block with automatic loading and unloading of marshalled variables
require 'rake/clean'
module MWsubs
extend self
def add_ext_sub(filename_in, ext_in)
filename = filename_in.to_s
# remove the period from the ext if it is there
ext = (ext_in[/^\./]) ? ext_in[1..-1] : ext_in
# add the extension unless it is alerady there
(filename[/\.#{ext}$/]) ? filename : "#{filename}.#{ext}"
end
def add_ext(filename, ext)
return nil if filename.nil?
if filename.is_a? Array
filename.map{|f| add_ext_sub(f, ext)}
else
add_ext_sub(filename, ext)
end
end
def add_marshal(filename)
add_ext(filename, '.marshal')
end
def marshal_save(object, filename)
# will add '.marshal' to the end of the filename if it isn't already there
File.open(add_marshal(filename), 'w') {|io| Marshal.dump(object, io)}
end
def marshal_load(filename)
#will add '.marshal' to the filename if necessary
File.open(add_marshal(filename)) {|io| Marshal.load(io)}
end
def load_inputs(filenames)
[*filenames].map{|f| marshal_load(f)}
end
def save_outputs(objects_in, filenames_in)
return if objects_in.nil?
return if filenames_in.nil? || filenames_in.empty?
filenames = [*filenames_in]
objects = (filenames.count == 1) ? [objects_in] : objects_in
Hash[objects.zip(filenames)].each {|o,f| marshal_save(o, f)}
end
def check_outputs(outputs, output_name_ar)
n_expect = output_name_ar.count
case n_expect
when 0 # NP, the block might return an argument, but we don't need to save it
when 1
raise "Error: expecting an output from the block" if outputs.nil?
# if we get an array of outputs they will just be mapped to a single marshal file
else
raise "Error: expecting #{n_expect} outputs from block but got none" if outputs.nil?
n_received = outputs.count
raise "Error: expecting #{n_expect} outputs from block but got #{n_received} instead" if n_expect != n_received
end
end
end
module Marshal_wrap
extend self
def marshal_wrap(*output_name_ar, &block)
marsh_output_name_ar = MWsubs.add_marshal(output_name_ar)
# rake file tasks can only accept one file as a target
target_file = marsh_output_name_ar[0]
params = block.parameters.map{|p| p[1]}
file target_file => MWsubs.add_marshal(params)
file target_file do |f|
puts "Making #{f.name}"
inputs = MWsubs.load_inputs(params)
outputs = block.(inputs)
MWsubs.check_outputs(outputs, output_name_ar)
MWsubs.save_outputs(outputs, output_name_ar)
end
task default: target_file
CLOBBER.include(marsh_output_name_ar)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment