Skip to content

Instantly share code, notes, and snippets.

@sergeych
Created June 21, 2017 20:02
Show Gist options
  • Save sergeych/a2a30f1bdbb484634e5383aad21dc34f to your computer and use it in GitHub Desktop.
Save sergeych/a2a30f1bdbb484634e5383aad21dc34f to your computer and use it in GitHub Desktop.
require ruby sources from zip files
#
# Tools to load ruby sources with require from inside compressed zips.
#
# real.sergeych@gmail.com, MIT license. No warranty.
#
require 'rubygems'
require 'zip'
alias require_old require
$require_from_zip_global_binding = binding
# Tool to load ruby dependencies (require) from set of zip files.
# First, pack your directory packs to one or more zip (e.g. vendors/),
# then register it:
#
# require 'require_from_zip'
#
# RequireFromZip.register 'zipfile1.zip', 'zipfile2.zip'
#
# now you can require your files from inside these zip as usual.
#
class RequireFromZip
@zipped = {}
class Entry < Struct.new(:name, :source)
def load
if !@loaded
eval source, $require_from_zip_global_binding, name
@loaded = true
# we don't need it anymore
self.source = nil
end
true
end
end
# Rgister zip files with sources qhich then can be required as usual.
#
# @param [Object] one or more zip file names
def self.register *zipfiles
zipfiles.each {|x| register_zipfile x}
end
private
def self.register_zipfile x
Zip::File.open(x) do |zip_file|
# Handle entries one by one
zip_file.each do |entry|
# Extract to file/directory/symlink
if entry.name.end_with? ('.rb')
content = entry.get_input_stream.read
@zipped[entry.name[0...-3]] = Entry.new(entry.name, content)
end
end
end
end
def self.do_require name
e = @zipped[name] and e.load
end
end
def require name
RequireFromZip.do_require(name) or require_old(name)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment