From: transfire@... Date: 2006-08-04T02:05:10+09:00 Subject: remote require I know there are other solutions to this out there. Just wanted to share my work/play at it. I was trying to make it reletvely secure without being too much a pain to use. This is was I arrived at. Usage looks like this: remote_source 'fruitapp', 'http://roll.rubyforge.org/source/fruitapp/lib/fruitapp/1.0.0/' remote_dependency '9de3cd6daece5f07aa3ddb0319a21415', 'tryme.rb' require 'fruitapp/tryme.rb' The MD5 checksum of course is there to help ensure you get what you expect. Of course that's the most time consuming part becasue you have to keep those upto date with new versions. Anyway, just thought I'd share it just in case it interested anyone. Here's the code: # --- remote_require.rb require 'open-uri' require 'digest/md5' require 'fileutils' REMOTE_CACHE = File.expand_path( '~/.lib/site_ruby/1.8/' ) FileUtils.mkdir_p REMOTE_CACHE unless File.directory? REMOTE_CACHE $:.unshift REMOTE_CACHE $current_source = nil $current_source_stack = [] $remote_source = nil $remote_dependency = {} module Kernel class ChecksumError < LoadError ; end def remote_source( ref, uri ) $remote_source = { :ref=>ref.chomp('/'), :uri=>uri.chomp('/') } end def remote_dependency( md5sum, file ) raise "dependency without source" unless $remote_source $remote_dependency[ File.join( $remote_source[:ref], file ) ] = { :ref => $remote_source[:ref], :file => file, :uri => $remote_source[:uri], :md5 => md5sum } end req = method(:require) define_method :require do |fname| if r = $remote_dependency[fname] $current_source_stack << $current_source $current_source = r end begin req.call fname rescue LoadError => e # Bit of a shortcoming here since it's not very efficient to # be searching an remote location for multiple matches. # .so suffix must be specified explicity on the remote end. fname = fname + '.rb' unless fname =~ /\.rb$/ or fname =~ /\.so$/ raise e unless $current_source s = $current_source url = fname.sub( /^#{s[:ref]}/, s[:uri] ) $stderr << "remote require -- " + url if $DEBUG rf = URI.parse( url ).read if r unless Digest::MD5.new( rf ).hexdigest == s[:md5] # TODO checksum raise ChecksumError.new(e) end end newfile = File.join( REMOTE_CACHE, fname ) newdir = File.dirname( newfile ) FileUtils.mkdir_p newdir File.open( newfile, 'w+' ) do |f| f << rf end retry ensure $current_source = $current_source_stack.pop if r end end end