instiki/lib/zip/ziprequire.rb

91 lines
2.2 KiB
Ruby

# With ziprequire you can load ruby modules from a zip file. This means
# ruby's module include path can include zip-files.
#
# The following example creates a zip file with a single entry
# <code>log/simplelog.rb</code> that contains a single function
# <code>simpleLog</code>:
#
# require 'zip/zipfilesystem'
#
# Zip::ZipFile.open("my.zip", true) {
# |zf|
# zf.file.open("log/simplelog.rb", "w") {
# |f|
# f.puts "def simpleLog(v)"
# f.puts ' Kernel.puts "INFO: #{v}"'
# f.puts "end"
# }
# }
#
# To use the ruby module stored in the zip archive simply require
# <code>zip/ziprequire</code> and include the <code>my.zip</code> zip
# file in the module search path. The following command shows one
# way to do this:
#
# ruby -rzip/ziprequire -Imy.zip -e " require 'log/simplelog'; simpleLog 'Hello world' "
#$: << 'data/rubycode.zip' << 'data/rubycode2.zip'
require 'zip/zip'
class ZipList #:nodoc:all
def initialize(zipFileList)
@zipFileList = zipFileList
end
def get_input_stream(entry, &aProc)
@zipFileList.each {
|zfName|
Zip::ZipFile.open(zfName) {
|zf|
begin
return zf.get_input_stream(entry, &aProc)
rescue Errno::ENOENT
end
}
}
raise Errno::ENOENT,
"No matching entry found in zip files '#{@zipFileList.join(', ')}' "+
" for '#{entry}'"
end
end
module Kernel #:nodoc:all
alias :oldRequire :require
def require(moduleName)
zip_require(moduleName) || oldRequire(moduleName)
end
def zip_require(moduleName)
return false if already_loaded?(moduleName)
get_resource(ensure_rb_extension(moduleName)) {
|zis|
eval(zis.read); $" << moduleName
}
return true
rescue Errno::ENOENT => ex
return false
end
def get_resource(resourceName, &aProc)
zl = ZipList.new($:.grep(/\.zip$/))
zl.get_input_stream(resourceName, &aProc)
end
def already_loaded?(moduleName)
moduleRE = Regexp.new("^"+moduleName+"(\.rb|\.so|\.dll|\.o)?$")
$".detect { |e| e =~ moduleRE } != nil
end
def ensure_rb_extension(aString)
aString.sub(/(\.rb)?$/i, ".rb")
end
end
# Copyright (C) 2002 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.